Author: ekoneil
Date: Wed Nov 10 12:40:31 2004
New Revision: 57363

Added:
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/ColumnModel.java
   (contents, props changed)
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/ColumnsModel.java
   (contents, props changed)
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/DataGridUtil.java
   (contents, props changed)
   
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/misc/customHeaderStyle.jsp
   (contents, props changed)
   
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridCustomHeaderStyle.xml
Removed:
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/AbstractColumnModel.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/impl/AbstractHtmlColumnModel.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/impl/AnchorColumnModel.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/impl/ImageColumnModel.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/impl/LiteralColumnModel.java
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/PagerModel.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/AbstractHtmlColumn.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/Caption.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/ConfigurePager.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/Footer.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/src/tags-databinding/org/apache/beehive/netui/tags/databinding/pageinput/DeclarePageInput.java
   
incubator/beehive/trunk/netui/src/util/org/apache/beehive/netui/util/HtmlExceptionFormatter.java
   
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/model/index.jsp
   
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
   incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/B40031.xml
Log:
Significant rework of the data grid.

- delete the Model objects and switch entirely to simple tags.  The model 
objects may come back at some point to support features like column reordering 
and programmatic grids, but they weren't adding value at this point.
- lots of code cleanup
- fixup the declarePageInput tag to be simple (it's cheaper) and to remove tag 
getters
- fixup the HtmlExceptionFormatter to print n-levels of 
(Servlet|Jsp|EL)Exception object root causes.  So, if there are nested 
JspExceptions, the nested, nested root cause will be printed.
- implement JavaScript / style support on grid header <th>s
- add a BVT test for this feature

BB: self
DRT: NetUI pass
BVT: NetUI pass



Added: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/ColumnModel.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/ColumnModel.java
     Wed Nov 10 12:40:31 2004
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.model;
+
+/**
+ */
+public class ColumnModel {
+
+    private ColumnsModel _columnsModel = null;
+
+    public ColumnModel(ColumnsModel columns)
+    {
+        _columnsModel = columns;
+    }
+
+    public boolean isRenderingHeader() {
+        return _columnsModel.getRenderState() == 
ColumnsModel.HEADER_RENDER_STATE;
+    }
+
+    public boolean isRenderingData() {
+        return _columnsModel.getRenderState() == 
ColumnsModel.DATA_RENDER_STATE;
+    }
+}

Added: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/ColumnsModel.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/ColumnsModel.java
    Wed Nov 10 12:40:31 2004
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.model;
+
+/**
+ *
+ */
+public class ColumnsModel {
+
+    public static final int DATA_RENDER_STATE = 0;
+    public static final int HEADER_RENDER_STATE = 1;
+    public static final int NO_RENDER_STATE = 2;
+
+    private int _renderState = NO_RENDER_STATE;
+
+    public int getRenderState() {
+        return _renderState;
+    }
+
+    public void setRenderState(int _renderState) {
+        this._renderState = _renderState;
+    }
+}

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 Nov 10 12:40:31 2004
@@ -39,14 +39,14 @@
  */
 public class DataGridModel
 {
-    private static final Logger _logger = 
Logger.getInstance(DataGridModel.class);
+    public static final int START_RENDER_STATE = 10;
+    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;
 
     private String _name = null;
-    private ArrayList _columns = null;
-    private Iterator _columnIterator = null;
     private StylePolicy _cssPolicy = null;
-    private SortService _sortService = null;
-    private FilterService _filterService = null;
     private PagerService _pagerService = null;
     private IPagerRenderer _pagerRenderer = null;
     private PagerModel _pagerModel = null;
@@ -54,19 +54,25 @@
     private PagedDataSet _dataSet = null;
     private TableRenderer _tableRenderer = null;
 
-    public DataGridModel(JspContext jspContext, String name)
+    private SortService _sortService = null;
+    private FilterService _filterService = null;
+
+    private int _renderState = START_RENDER_STATE;
+
+    public DataGridModel(JspContext jspContext, String name, PagedDataSet 
dataSet)
     {
         super();
 
         _name = name;
         _jspContext = jspContext;
+        _dataSet = dataSet;
         _pagerModel = new PagerModel(this);
     }
 
-    public void initialize()
-    {
+    public void initialize() {
         HttpServletRequest request = 
(HttpServletRequest)((PageContext)_jspContext).getRequest();
 
+        /* todo: need to move to using absolute page references in the URL */
         int lastPage = 
(int)Math.ceil((float)_dataSet.getSize()/(float)_pagerModel.getPageSize());
         assert lastPage >= 0;
         int startRenderWindow = 
(_pagerModel.getCurrentPage()-1)*_pagerModel.getPageSize();
@@ -82,18 +88,15 @@
         _pagerModel.initialize();
         _tableRenderer = new TableRenderer(request);
     }
-    
-    public void uninitialize()
-    {
+
+    public int getRenderState() {
+        return _renderState;
     }
 
-    public void addColumn(AbstractColumnModel column)
+    public void setRenderState(int renderState)
     {
-        if(_columns == null)
-            _columns = new ArrayList();
-
-        column.setDataGridModel(this);
-        _columns.add(column);
+        /* todo: need to assert that the correct transitions are being made */
+        _renderState = renderState;
     }
 
     public void renderPager(AbstractRenderAppender appender)
@@ -105,71 +108,6 @@
         appender.append(_pagerRenderer.render());
     }
 
-    public void openTable(AbstractRenderAppender appender)
-    {
-        TableTag.State state = new TableTag.State();
-        state.styleClass = _cssPolicy.getTableClass();
-        _tableRenderer.openTable(state, appender);
-    }
-
-    public void closeTable(AbstractRenderAppender appender)
-    {
-        _tableRenderer.closeTable(appender);
-        appender.append("\n");
-    }
-
-    public void openCaption(AbstractRenderAppender appender)
-    {
-        _tableRenderer.openCaption(appender);
-    }
-
-    public void closeCaption(AbstractRenderAppender appender)
-    {
-        _tableRenderer.closeCaption(appender);
-    }
-
-    public final void openHeaderRow(AbstractRenderAppender appender)
-    {
-        TrTag.State state = new TrTag.State();
-        state.styleClass = _cssPolicy.getHeaderRowClass();
-
-        _tableRenderer.openHeaderRow(state, appender);
-    }
-
-    public void closeHeaderRow(AbstractRenderAppender appender)
-    {
-        _tableRenderer.closeHeaderRow(appender);
-    }
-
-    public void openDataRow(AbstractRenderAppender appender)
-    {
-        TrTag.State state = new TrTag.State();
-        int index = getCurrentIndex();
-        if(index % 2 == 0)
-            state.styleClass = _cssPolicy.getRowClass();
-        else state.styleClass = _cssPolicy.getAltRowClass();
-
-        _tableRenderer.openTableRow(state, appender);
-    }
-
-    public void closeDataRow(AbstractRenderAppender appender)
-    {
-        _tableRenderer.closeTableRow(appender);
-    }
-
-    public void openFooterRow(AbstractRenderAppender appender)
-    {
-        TrTag.State state = new TrTag.State();
-        state.styleClass = _cssPolicy.getFooterRowClass();
-
-        _tableRenderer.openFooterRow(state, appender);
-    }
-
-    public void closeFooterRow(AbstractRenderAppender appender)
-    {
-        _tableRenderer.closeFooterRow(appender);
-    }
-
     public void setDataSet(PagedDataSet dataSet) {
         _dataSet = dataSet;
     }
@@ -209,23 +147,6 @@
         return _jspContext;
     }
 
-    public List getColumns()
-    {
-        if(_columns != null)
-            return Collections.unmodifiableList(_columns);
-        else return Collections.EMPTY_LIST;
-    }
-
-    public AbstractColumnModel getColumn(int index)
-    {
-        assert _columns != null;
-        assert index < _columns.size();
-
-        AbstractColumnModel cm = (AbstractColumnModel)_columns.get(index);
-
-        return cm;
-    }
-
     public void setCssPolicy(StylePolicy cssPolicy) {
         _cssPolicy = cssPolicy;
     }
@@ -270,23 +191,6 @@
 
     public boolean hasNextDataItem()
     {
-        boolean hasNext = _dataSet.hasNext();
-        if(_logger.isDebugEnabled()) _logger.debug("data set hasNext: " + 
hasNext);
-        return hasNext;
-    }
-
-    public AbstractColumnModel getNextColumnModel()
-    {
-        if(_columnIterator == null)
-            resetColumnIterator();
-
-        if(_columnIterator.hasNext())
-            return (AbstractColumnModel)_columnIterator.next();
-        else throw new NoSuchElementException("There are no more ColumnModel 
objects available in this iterator");
-    }
-
-    public void resetColumnIterator()
-    {
-        _columnIterator = _columns.iterator();
+        return _dataSet.hasNext();
     }
 }

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/PagerModel.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/PagerModel.java
      (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/PagerModel.java
      Wed Nov 10 12:40:31 2004
@@ -26,11 +26,9 @@
 import javax.servlet.http.HttpServletRequest;
 
 /**
- *
  * todo: need to throw IllegalStateExceptions when pager model getters are 
called before the PagerModel is intiailized
  */
-public class PagerModel
-{
+public class PagerModel {
     private static final Logger _logger = Logger.getInstance(PagerModel.class);
     private static final int DEFAULT_PAGE_SIZE = 10;
 
@@ -51,114 +49,137 @@
     private int _prevPage = -1;
     private int _nextPage = -1;
 
-    public PagerModel(DataGridModel model)
-    {
+    public PagerModel(DataGridModel model) {
         _model = model;
         _pagerService = model.getPagerService();
     }
 
-    public void initialize()
-    {
+    public void initialize() {
         calculatePageBoundaries();
     }
 
-    public String getAction() {return _action;}
-    public void setAction(String action) {_action = action;}
-    
-    public int getPageSize() {return _pageSize != null ? _pageSize : 
DEFAULT_PAGE_SIZE;}
-    public void setPageSize(int pageSize)
-    {
+    public String getAction() {
+        return _action;
+    }
+
+    public void setAction(String action) {
+        _action = action;
+    }
+
+    public int getPageSize() {
+        return _pageSize != null ? _pageSize : DEFAULT_PAGE_SIZE;
+    }
+
+    public void setPageSize(int pageSize) {
         // todo: error checking to ensure that the page size is within a 
reasonable range
         _pageSize = pageSize;
 
         calculatePageBoundaries();
     }
 
-    public String getFormat() {return _format;}
-    public void setFormat(String format) {_format = format;}
+    public String getFormat() {
+        return _format;
+    }
+
+    public void setFormat(String format) {
+        _format = format;
+    }
+
+    public String getPageHref() {
+        return _pageHref;
+    }
+
+    public void setPageHref(String pageHref) {
+        _pageHref = pageHref;
+    }
 
-    public String getPageHref() {return _pageHref;}
-    public void setPageHref(String pageHref) {_pageHref = pageHref;}
+    public String getPageAction() {
+        return _pageAction;
+    }
 
-    public String getPageAction() {return _pageAction;}
-    public void setPageAction(String pageAction) {_pageAction = pageAction;}
+    public void setPageAction(String pageAction) {
+        _pageAction = pageAction;
+    }
 
     // todo: what needs to happen here with re-writing the URI when it's an 
HREF?
-    public String getPageUri()
-    {
+    public String getPageUri() {
         String pageUri = null;
-        if(_pageAction != null)
-        {
+        if (_pageAction != null) {
             PageContext pageContext = 
JspUtil.getPageContext(_model.getJspContext());
-            String qualifiedAction = 
PageflowTagUtils.qualifiedAction(pageContext.getServletContext(),_pageAction);
+            String qualifiedAction = 
PageflowTagUtils.qualifiedAction(pageContext.getServletContext(), _pageAction);
             pageUri = PageflowTagUtils.createActionURL((HttpServletRequest) 
pageContext.getRequest(), qualifiedAction);
-        }
-        else if(_pageHref != null)
-        {
+        } else if (_pageHref != null) {
             pageUri = _pageHref;
         }
 
         return pageUri;
     }
 
-    public PagerService getPagerService() {return _pagerService;}
+    public PagerService getPagerService() {
+        return _pagerService;
+    }
 
-    public int getCurrentPageFromURL() {return _pagerService.getCurrentPage();}
+    public int getCurrentPageFromURL() {
+        return _pagerService.getCurrentPage();
+    }
 
-    public int getDataSetSize() {return _dataSetSize;}
+    public int getDataSetSize() {
+        return _dataSetSize;
+    }
 
-    public int getLastPage() {return _lastPage;}
+    public int getLastPage() {
+        return _lastPage;
+    }
 
-    public int getPreviousPage() {return _prevPage;}
+    public int getPreviousPage() {
+        return _prevPage;
+    }
 
-    public int getNextPage() {return _nextPage;}
+    public int getNextPage() {
+        return _nextPage;
+    }
 
-    public String[] getPageParamValues()
-    {
+    public String[] getPageParamValues() {
         String[] params = new String[getLastPage()];
 
-        for(int i = 1; i <= params.length; i++)
-        {
-            params[i-1] = _pagerService.buildQueryParamValueForPage(i);
+        for (int i = 1; i <= params.length; i++) {
+            params[i - 1] = _pagerService.buildQueryParamValueForPage(i);
         }
 
         return params;
     }
 
-    public String getPageParamKey()
-    {
+    public String getPageParamKey() {
         return PagerService.DEFAULT_PAGE_PARAM_NAME;
     }
 
 
-    public int getCurrentPage()
-    {
-        if(_currentPage == null)
+    public int getCurrentPage() {
+        if (_currentPage == null)
             return getCurrentPageFromURL();
-        else return _currentPage.intValue();
+        else
+            return _currentPage.intValue();
     }
 
-    public void setCurrentPage(int currentPage)
-    {
+    public void setCurrentPage(int currentPage) {
         // todo: need to recalculate the computed page information given the 
new current page.
         // todo: need to check that the new 'current' page is in range given 
the first/last boundaries
         _currentPage = new Integer(currentPage);
     }
 
-    private void calculatePageBoundaries()
-    {
+    private void calculatePageBoundaries() {
         assert _pagerService != null;
 
         _dataSetSize = _model.getDataSetSize();
         int pageSize = (_pageSize != null ? _pageSize : DEFAULT_PAGE_SIZE);
         _currentPage = _pagerService.getCurrentPage();
 
-        _lastPage = (int)Math.ceil((float)_dataSetSize / (float)pageSize);
+        _lastPage = (int) Math.ceil((float) _dataSetSize / (float) pageSize);
 
-        if(_currentPage > _lastPage)
+        if (_currentPage > _lastPage)
             _currentPage = _lastPage;
 
-        _prevPage = _currentPage-1;
-        _nextPage = _currentPage+1;
+        _prevPage = _currentPage - 1;
+        _nextPage = _currentPage + 1;
     }
 }

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 Nov 10 12:40:31 2004
@@ -21,224 +21,187 @@
 import javax.servlet.jsp.tagext.JspFragment;
 import javax.servlet.jsp.JspException;
 
-import org.apache.beehive.netui.databinding.datagrid.model.AbstractColumnModel;
+import org.apache.beehive.netui.databinding.datagrid.model.DataGridModel;
+import org.apache.beehive.netui.databinding.datagrid.model.ColumnModel;
+import org.apache.beehive.netui.databinding.datagrid.model.ColumnsModel;
 
 import org.apache.beehive.netui.tags.AbstractSimpleTag;
 import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender;
 import org.apache.beehive.netui.tags.rendering.StringBuilderRenderAppender;
 import org.apache.beehive.netui.tags.html.Formattable;
+import org.apache.beehive.netui.tags.html.FormatTag;
 import org.apache.beehive.netui.tags.html.FormatTag.Formatter;
 import org.apache.beehive.netui.util.logging.Logger;
 
 import java.io.IOException;
 import java.io.StringWriter;
+import java.util.ArrayList;
 
 /**
  *
  */
 public abstract class AbstractColumn
-    extends AbstractSimpleTag
-    implements Formattable
-{
-    private static final Logger _logger = 
Logger.getInstance(AbstractColumn.class);
+        extends AbstractSimpleTag
+        implements Formattable {
 
-    private Columns _parent = null;
-    private DataGrid _dataGrid = null;
+    private static final Logger _logger = 
Logger.getInstance(AbstractColumn.class);
 
-    private Boolean _filterable = null;
-    private Boolean _sortable = null;
-    private String _sortExpression = null;
-    private String _filterExpression = null;
-    private String _headerText = null;
-    private String _headerStyle = null;
-    private String _headerStyleClass = null;
+    static final String COLUMN_MODEL_KEY = "column";
 
-    /**
-     * @netui:attribute required="false" rtexprvalue="true"
-     */
-    public void setHeaderText(String headerText) {_headerText = headerText;}
+    private static final String EMPTY_CELL = "&nbsp;";
+    private static final String EMPTY_STRING = "";
 
-    /**
-     * @netui:attribute required="false" rtexprvalue="true"
-     */
-    public void setHeaderStyle(String headerStyle) {_headerStyle = 
headerStyle;}
+    private String _headerText = null;
+    private DataGridModel _dataGridModel = null;
+    private ArrayList _formatters = null;
 
     /**
      * @netui:attribute required="false" rtexprvalue="true"
      */
-    public void setHeaderStyleClass(String headerStyleClass) 
{_headerStyleClass = headerStyleClass;}
+    public void setHeaderText(String headerText) {
+        _headerText = headerText;
+    }
 
     /**
-     *
      * @throws JspException
      * @throws IOException
      */
     public void doTag()
-        throws JspException, IOException
-    {
+            throws JspException, IOException {
+
+        /* todo: this should be done in a TLV */
         JspTag parent = findAncestorWithClass(this, Columns.class);
-        if(!(parent instanceof Columns))
+        if (!(parent instanceof Columns))
             throw new JspException("A Column tag must be contained inside of a 
Columns tag.");
 
-        int gridRenderState = getDataGridTag().getRenderState();
+        int gridRenderState = 
DataGridUtil.getDataGridModel(getJspContext()).getRenderState();
 
         // when starting to render, the AbstractColumnModel associated with 
this tag needs to be created
-        if(gridRenderState == DataGrid.START_RENDER_STATE)
-        {
-            AbstractColumnModel cm = createColumnModel();
-
-            assert cm != null : "Column type " + getClass().getName() + " 
created a null ColumnModel";
-
-            setColumnModel(cm);
-            getColumnsTag().addColumn(cm);
+        if (gridRenderState == DataGridModel.START_RENDER_STATE) {
+            return;
         }
         // otherwise, the ColumnModel associated with this tag
         // needs to be fetched from the <columns> tag for the current
         // iteration
-        else
-        {
-            int columnsRenderState = getColumnsTag().getRenderState();
-
-            assert columnsRenderState == AbstractColumnModel.DATA_RENDER_STATE 
||
-                   columnsRenderState == 
AbstractColumnModel.HEADER_RENDER_STATE;
-
-            getColumnsTag().loadNextColumn();
-            AbstractColumnModel cm = getColumnModel();
+        else {
 
-            assert cm != null : "The ColumnModel received by the grid column 
was null";
+            StringBuilder content = new StringBuilder();
+            AbstractRenderAppender appender = new 
StringBuilderRenderAppender(content);
 
-            setColumnModel(cm);
-            cm.startCell();
-            cm.setHeaderText(_headerText);
+            ColumnsModel columns = 
DataGridUtil.getColumnsModel(getJspContext());
+            assert columns != null;
 
-            if(_filterable != null)
-                cm.setFilterable(_filterable);
-            cm.setFilterExpression(_filterExpression);
+            ColumnModel model = new ColumnModel(columns);
 
-            if(_sortable != null)
-                cm.setSortable(_sortable);
-            cm.setSortExpression(_sortExpression);
+            int renderState = columns.getRenderState();
 
-            cm.setRenderState(columnsRenderState);
+            assert renderState == ColumnsModel.DATA_RENDER_STATE ||
+                   renderState == ColumnsModel.HEADER_RENDER_STATE;
 
-            int renderState = getColumnsTag().getRenderState();
-            StringBuilder content = new StringBuilder();
-            AbstractRenderAppender appender = new 
StringBuilderRenderAppender(content);
+            applyAttributes();
 
             // todo: need to assert that the identityHashCode of 'cm' is 
well-known
 
-            if (_logger.isDebugEnabled())
-            {
+            if (_logger.isDebugEnabled()) {
                 _logger.debug("current column\n\trender state: " + 
renderState);
-                _logger.debug("\tmodel: " + cm);
-                _logger.debug("\tidentity hash code: " + 
System.identityHashCode(cm));
+                _logger.debug("\tidentity hash code: " + 
System.identityHashCode(model));
             }
 
-            assert cm != null;
+            getJspContext().setAttribute(COLUMN_MODEL_KEY, model);
 
             JspFragment fragment = getJspBody();
             StringWriter sw = new StringWriter();
             String bodyContent = null;
-            if(fragment != null)
-            {
+            if (fragment != null) {
                 fragment.invoke(sw);
                 bodyContent = sw.toString();
             }
 
-            // allow subclasses to apply attributes to their ColumnModel 
objects
-            // this needs to happen after the JspBody is rendered in
-            // case there are cooperating tags that need to be applied as 
attributes
-            applyAttributes();
+            if (renderState == ColumnsModel.HEADER_RENDER_STATE) {
 
-            if (renderState == AbstractColumnModel.HEADER_RENDER_STATE)
-            {
-                if (_logger.isDebugEnabled()) _logger.debug("render a column's 
header cell");
-
-                cm.openHeaderCell(appender);
-                if(_headerText != null)
-                    cm.renderHeader(appender);
-                else if(bodyContent != null)
+                openHeaderCell(appender);
+                if (_headerText != null)
+                    renderHeader(appender);
+                else if (bodyContent != null)
                     appender.append(bodyContent);
-                cm.closeHeaderCell(appender);
-            }
-            else if (renderState == AbstractColumnModel.DATA_RENDER_STATE)
-            {
-                if (_logger.isDebugEnabled()) _logger.debug("render a column's 
data cell");
-
-                cm.openDataCell(appender);
-                cm.renderDataCell(appender);
-                cm.closeDataCell(appender);
+                closeHeaderCell(appender);
+            } else if (renderState == ColumnsModel.DATA_RENDER_STATE) {
+
+                openDataCell(appender);
+                renderDataCell(appender);
+                closeDataCell(appender);
             }
 
             if (content != null && content.length() > 0)
                 getJspContext().getOut().println(content.toString());
-
-            cm.endCell();
-            cm.setRenderState(AbstractColumnModel.NO_RENDER_STATE);
         }
 
-        getColumnsTag().unloadColumn();
+        getJspContext().removeAttribute(COLUMN_MODEL_KEY);
 
         return;
     }
 
-    public void addFormatter(Formatter formatter)
-    {
-        getColumnModel().addFormatter(formatter);
+    protected abstract void openHeaderCell(AbstractRenderAppender appender);
+
+    protected abstract void closeHeaderCell(AbstractRenderAppender appender);
+
+    protected abstract void openDataCell(AbstractRenderAppender appender);
+
+    protected abstract void closeDataCell(AbstractRenderAppender appender);
+
+    public void addFormatter(Formatter formatter) {
+        if(_formatters == null)
+            _formatters = new ArrayList();
+
+        _formatters.add(formatter);
     }
 
     /**
      * Indicate that a formatter has reported an error so the formatter should 
output it's
      * body text.
      */
-    public void formatterHasError()
-    {
+    public void formatterHasError() {
         // todo: error reporting!
     }
 
-    public AbstractColumnModel getColumnModel()
-    {
-        return 
(AbstractColumnModel)getJspContext().getAttribute(Columns.COLUMN_MODEL_KEY);
+    protected void applyAttributes()
+        throws JspException {
+        /* todo: apply the global sort / filter attributes here */
     }
 
-    protected abstract AbstractColumnModel createColumnModel();
+    protected void renderHeader(AbstractRenderAppender appender) {
 
-    protected abstract void setColumnModel(AbstractColumnModel model);
+        if (_headerText == null)
+            renderEmptyCell(appender);
+        else
+            appender.append(_headerText != null ? _headerText.toString() : 
EMPTY_STRING);
+    }
 
-    protected void applyAttributes()
-        throws JspException
-    {
-        AbstractColumnModel cm = getColumnModel();
-
-        if(_headerStyle != null)
-            cm.setHeaderStyle(_headerStyle);
-
-        if(_headerStyleClass != null)
-            cm.setHeaderStyleClass(_headerStyleClass);
-    }
-
-    protected Columns getColumnsTag()
-        throws JspException
-    {
-        if(_parent != null)
-            return _parent;
-
-        JspTag parent = getParent();
-        if(!(parent instanceof Columns))
-            throw new JspException("A data gird column tag must be contained 
inside of a Columns tag.");
-        else return (_parent = (Columns)getParent());
-    }
-
-    protected DataGrid getDataGridTag()
-        throws JspException
-    {
-        if(_dataGrid != null)
-            return _dataGrid;
-
-        Columns columns = getColumnsTag();
-        JspTag expectedDataGrid = columns.getParent();
-        if(!(expectedDataGrid instanceof DataGrid))
-            throw new JspException("The Columns tag must be contained inside 
of a DataGrid tag.");
-        else return (_dataGrid = (DataGrid)expectedDataGrid);
+    protected abstract void renderDataCell(AbstractRenderAppender appender);
+
+    protected void renderEmptyCell(AbstractRenderAppender appender) {
+        appender.append(EMPTY_CELL);
+    }
+
+    protected String formatText(Object text) {
+        if (text == null)
+            return null;
+
+        if (_formatters == null)
+            return text.toString();
+
+        for (int i = 0; i < _formatters.size(); i++) {
+            FormatTag.Formatter currentFormatter = (FormatTag.Formatter) 
_formatters.get(i);
+            assert currentFormatter != null;
+            try {
+                text = currentFormatter.format(text);
+            } catch (JspException e) {
+                // todo: need a way to register errors in the datagridmodel so 
that they can be reported back to the rendering engine
+                if (_logger.isErrorEnabled())
+                    _logger.error("A formatter of type \"" + 
currentFormatter.getClass().getName() + "\" threw an exception " + e, e);
+            }
+        }
+
+        return text.toString();
     }
 }

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AbstractHtmlColumn.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AbstractHtmlColumn.java
       (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AbstractHtmlColumn.java
       Wed Nov 10 12:40:31 2004
@@ -17,190 +17,400 @@
  */
 package org.apache.beehive.netui.tags.databinding.datagrid;
 
-import javax.servlet.jsp.JspException;
-
-import 
org.apache.beehive.netui.databinding.datagrid.model.impl.AbstractHtmlColumnModel;
+import org.apache.beehive.netui.databinding.datagrid.model.DataGridModel;
 import org.apache.beehive.netui.tags.IAttributeConsumer;
+import org.apache.beehive.netui.tags.html.HtmlConstants;
+import org.apache.beehive.netui.tags.rendering.ThTag;
+import org.apache.beehive.netui.tags.rendering.AbstractHtmlState;
+import org.apache.beehive.netui.tags.rendering.TdTag;
+import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender;
 import org.apache.beehive.netui.util.Bundle;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-
+/**
+ * TODO: need to support <netui:attribute> tags for the header table cell
+ * TODO: need to support .clear() to whack custom attributes
+ */
 public abstract class AbstractHtmlColumn
     extends AbstractColumn
     implements IAttributeConsumer
 {
-    private String _onClick;
-    private String _onDblClick;
-    private String _onKeyDown;
-    private String _onKeyUp;
-    private String _onKeyPress;
-    private String _onMouseDown;
-    private String _onMouseUp;
-    private String _onMouseMove;
-    private String _onMouseOut;
-    private String _onMouseOver;
-    private String _style;
-    private String _styleClass;
-    private String _title;
+    private static final String HEADER_FACET_NAME = "header";
+    private static final String DEFAULT_FACET_NAME = "default";
 
-    private ArrayList _attributeList;
+    private TdTag.State _tdState = new TdTag.State();
+    private ThTag.State _thState = new ThTag.State();
 
     /**
      * Sets the onClick javascript event.
-     * @param onClick - the onClick event.
      *
+     * @param onClick - the onClick event.
      * @jsptagref.attributedescription The onClick JavaScript event.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_onClick</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
onClick JavaScript event."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
      */
-    public void setOnClick(String onClick) {_onClick = onClick;}
+    public void setOnClick(String onClick) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONCLICK, onClick);
+    }
 
     /**
      * Sets the onDblClick javascript event.
-     * @param onDblClick - the onDblClick event.
      *
+     * @param onDblClick - the onDblClick event.
      * @jsptagref.attributedescription The onDblClick JavaScript event.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_onDblClick</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
onDblClick JavaScript event."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
      */
-    public void setOnDblClick(String onDblClick) {_onDblClick = onDblClick;}
+    public void setOnDblClick(String onDblClick) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONDBLCLICK, onDblClick);
+    }
 
     /**
      * Sets the onKeyDown javascript event.
-     * @param onKeyDown - the onKeyDown event.
      *
+     * @param onKeyDown - the onKeyDown event.
      * @jsptagref.attributedescription The onKeyDown JavaScript event.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_onKeyDown</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
onKeyDown JavaScript event."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
      */
-    public void setOnKeyDown(String onKeyDown) {_onKeyDown = onKeyDown;}
+    public void setOnKeyDown(String onKeyDown) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONKEYDOWN, onKeyDown);
+    }
 
     /**
      * Sets the onKeyUp javascript event.
-     * @param onKeyUp - the onKeyUp event.
      *
+     * @param onKeyUp - the onKeyUp event.
      * @jsptagref.attributedescription The onKeyUp JavaScript event.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_onKeyUp</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
onKeyUp JavaScript event."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
      */
-    public void setOnKeyUp(String onKeyUp) {_onKeyUp = onKeyUp;}
+    public void setOnKeyUp(String onKeyUp) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONKEYUP, onKeyUp);
+    }
 
     /**
      * Sets the onKeyPress javascript event.
-     * @param onKeyPress - the onKeyPress event.
      *
+     * @param onKeyPress - the onKeyPress event.
      * @jsptagref.attributedescription The onKeyPress JavaScript event.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_onKeyPress</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
onKeyPress JavaScript event."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
      */
-    public void setOnKeyPress(String onKeyPress) {_onKeyPress = onKeyPress;}
+    public void setOnKeyPress(String onKeyPress) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONKEYPRESS, onKeyPress);
+    }
 
     /**
      * Sets the onMouseDown javascript event.
-     * @param onMouseDown - the onMouseDown event.
      *
+     * @param onMouseDown - the onMouseDown event.
      * @jsptagref.attributedescription The onMouseDown JavaScript event.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_onMouseDown</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
onMouseDown JavaScript event."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
      */
-    public void setOnMouseDown(String onMouseDown) {_onMouseDown = 
onMouseDown;}
+    public void setOnMouseDown(String onMouseDown) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONMOUSEDOWN, onMouseDown);
+    }
 
     /**
      * Sets the onMouseUp javascript event.
-     * @param onMouseUp - the onMouseUp event.
      *
+     * @param onMouseUp - the onMouseUp event.
      * @jsptagref.attributedescription The onMouseUp JavaScript event.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_onMouseUp</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
onMouseUp JavaScript event."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
      */
-    public void setOnMouseUp(String onMouseUp) {_onMouseUp = onMouseUp;}
+    public void setOnMouseUp(String onMouseUp) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONMOUSEUP, onMouseUp);
+    }
 
     /**
      * Sets the onMouseMove javascript event.
-     * @param onMouseMove - the onMouseMove event.
      *
+     * @param onMouseMove - the onMouseMove event.
      * @jsptagref.attributedescription The onMouseMove JavaScript event.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_onMouseMove</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
onMouseMove JavaScript event."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
      */
-    public void setOnMouseMove(String onMouseMove) {_onMouseMove = 
onMouseMove;}
+    public void setOnMouseMove(String onMouseMove) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONMOUSEMOVE, onMouseMove);
+    }
 
     /**
      * Sets the onMouseOut javascript event.
-     * @param onMouseOut - the onMouseOut event.
      *
+     * @param onMouseOut - the onMouseOut event.
      * @jsptagref.attributedescription The onMouseOut JavaScript event.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_onMouseOut</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
onMouseOut JavaScript event."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
      */
-    public void setOnMouseOut(String onMouseOut) {_onMouseOut = onMouseOut;}
+    public void setOnMouseOut(String onMouseOut) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONMOUSEOUT, onMouseOut);
+    }
 
     /**
      * Sets the onMouseOver javascript event.
-     * @param onMouseOver - the onMouseOver event.
      *
+     * @param onMouseOver - the onMouseOver event.
      * @jsptagref.attributedescription The onMouseOver JavaScript event.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_onMouseOver</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
onMouseOver JavaScript event."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
      */
-    public void setOnMouseOver(String onMouseOver) {_onMouseOver = 
onMouseOver;}
+    public void setOnMouseOver(String onMouseOver) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONMOUSEOVER, onMouseOver);
+    }
 
     /**
      * Sets the style of the rendered html tag.
-     * @param style - the html style.
      *
+     * @param style - the html style.
      * @jsptagref.attributedescription The style.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_style</i>
      * @netui:attribute required="false"  rtexprvalue="true" description="The 
style."
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.JspStyleProperty" 
category="format"
      */
-    public void setStyle(String style) {_style = style;}
+    public void setStyle(String style) {
+        if("".equals(style)) return;
+
+        internalGetHtmlState().style = style;
+    }
 
     /**
      * Sets the style class of the rendered html tag.
-     * @param styleClass - the html style class.
      *
+     * @param styleClass - the html style class.
      * @jsptagref.attributedescription The style class.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_style_class</i>
      * @netui:attribute required="false"  rtexprvalue="true" description="The 
style class."
      * @netui.tldx:attribute category="Format"
      */
-    public void setStyleClass(String styleClass) {_styleClass = styleClass;}
+    public void setStyleClass(String styleClass) {
+        if("".equals(styleClass)) return;
+
+        internalGetHtmlState().styleClass = styleClass;
+    }
 
     /**
      * Sets the value of the title attribute.
+     *
      * @param title
+     * @jsptagref.attributedescription The title.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_title</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
title. "
+     * @netui.tldx:attribute category="misc"
+     */
+    public void setTitle(String title) {
+        
internalGetHtmlState().registerAttribute(AbstractHtmlState.ATTR_GENERAL, 
HtmlConstants.TITLE, title);
+    }
+
+    /**
+     * Sets the onClick javascript event.
+     *
+     * @param onClick - the onClick event.
+     * @jsptagref.attributedescription The onClick JavaScript event.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_onClick</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
onClick JavaScript event."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
+     */
+    public void setHeaderOnClick(String onClick) {
+        
internalGetThState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONCLICK, onClick);
+    }
+
+    /**
+     * Sets the onDblClick javascript event.
+     *
+     * @param onDblClick - the onDblClick event.
+     * @jsptagref.attributedescription The onDblClick JavaScript event.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_onDblClick</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
onDblClick JavaScript event."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
+     */
+    public void setHeaderOnDblClick(String onDblClick) {
+        
internalGetThState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONDBLCLICK, onDblClick);
+    }
+
+    /**
+     * Sets the onKeyDown javascript event.
      *
+     * @param onKeyDown - the onKeyDown event.
+     * @jsptagref.attributedescription The onKeyDown JavaScript event.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_onKeyDown</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
onKeyDown JavaScript event."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
+     */
+    public void setHeaderOnKeyDown(String onKeyDown) {
+        
internalGetThState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONKEYDOWN, onKeyDown);
+    }
+
+    /**
+     * Sets the onKeyUp javascript event.
+     *
+     * @param onKeyUp - the onKeyUp event.
+     * @jsptagref.attributedescription The onKeyUp JavaScript event.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_onKeyUp</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
onKeyUp JavaScript event."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
+     */
+    public void setHeaderOnKeyUp(String onKeyUp) {
+        
internalGetThState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONKEYUP, onKeyUp);
+    }
+
+    /**
+     * Sets the onKeyPress javascript event.
+     *
+     * @param onKeyPress - the onKeyPress event.
+     * @jsptagref.attributedescription The onKeyPress JavaScript event.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_onKeyPress</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
onKeyPress JavaScript event."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
+     */
+    public void setHeaderOnKeyPress(String onKeyPress) {
+        
internalGetThState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONKEYPRESS, onKeyPress);
+    }
+
+    /**
+     * Sets the onMouseDown javascript event.
+     *
+     * @param onMouseDown - the onMouseDown event.
+     * @jsptagref.attributedescription The onMouseDown JavaScript event.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_onMouseDown</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
onMouseDown JavaScript event."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
+     */
+    public void setHeaderOnMouseDown(String onMouseDown) {
+        
internalGetThState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONMOUSEDOWN, onMouseDown);
+    }
+
+    /**
+     * Sets the onMouseUp javascript event.
+     *
+     * @param onMouseUp - the onMouseUp event.
+     * @jsptagref.attributedescription The onMouseUp JavaScript event.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_onMouseUp</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
onMouseUp JavaScript event."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
+     */
+    public void setHeaderOnMouseUp(String onMouseUp) {
+        
internalGetThState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONMOUSEDOWN, onMouseUp);
+    }
+
+    /**
+     * Sets the onMouseMove javascript event.
+     *
+     * @param onMouseMove - the onMouseMove event.
+     * @jsptagref.attributedescription The onMouseMove JavaScript event.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_onMouseMove</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
onMouseMove JavaScript event."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
+     */
+    public void setHeaderOnMouseMove(String onMouseMove) {
+        
internalGetThState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONMOUSEMOVE, onMouseMove);
+    }
+
+    /**
+     * Sets the onMouseOut javascript event.
+     *
+     * @param onMouseOut - the onMouseOut event.
+     * @jsptagref.attributedescription The onMouseOut JavaScript event.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_onMouseOut</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
onMouseOut JavaScript event."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
+     */
+    public void setHeaderOnMouseOut(String onMouseOut) {
+        
internalGetThState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONMOUSEOUT, onMouseOut);
+    }
+
+    /**
+     * Sets the onMouseOver javascript event.
+     *
+     * @param onMouseOver - the onMouseOver event.
+     * @jsptagref.attributedescription The onMouseOver JavaScript event.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_onMouseOver</i>
+     * @netui:attribute required="false" rtexprvalue="true" description="The 
onMouseOver JavaScript event."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.EventPropertyClass" 
category="event"
+     */
+    public void setHeaderOnMouseOver(String onMouseOver) {
+        
internalGetThState().registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, 
HtmlConstants.ONMOUSEOUT, onMouseOver);
+    }
+
+    /**
+     * Sets the style of the rendered html tag.
+     *
+     * @param style - the html style.
+     * @jsptagref.attributedescription The style.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_style</i>
+     * @netui:attribute required="false"  rtexprvalue="true" description="The 
style."
+     * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.JspStyleProperty" 
category="format"
+     */
+    public void setHeaderStyle(String style) {
+        if ("".equals(style)) return;
+
+        internalGetThState().style = style;
+    }
+
+    /**
+     * Sets the style class of the rendered html tag.
+     *
+     * @param styleClass - the html style class.
+     * @jsptagref.attributedescription The style class.
+     * @jsptagref.databindable false
+     * @jsptagref.attributesyntaxvalue <i>string_style_class</i>
+     * @netui:attribute required="false"  rtexprvalue="true" description="The 
style class."
+     * @netui.tldx:attribute category="Format"
+     */
+    public void setHeaderStyleClass(String styleClass) {
+        if ("".equals(styleClass)) return;
+
+        internalGetThState().styleClass = styleClass;
+    }
+
+    /**
+     * Sets the value of the title attribute.
+     *
+     * @param title
      * @jsptagref.attributedescription The title.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_title</i>
      * @netui:attribute required="false" rtexprvalue="true" description="The 
title. "
      * @netui.tldx:attribute category="misc"
      */
-    public void setTitle(String title) {_title = title;}
+    public void setHeaderTitle(String title) {
+        internalGetThState().registerAttribute(AbstractHtmlState.ATTR_GENERAL, 
HtmlConstants.TITLE, title);
+    }
 
     /**
      * Base support for the <code>attribute</code> tag.  This requires that 
the tag buffer their body and
@@ -214,63 +424,87 @@
      */
     public void setAttribute(String name, String value, String facet)
     {
-        if (facet != null) {
+        /* TODO: need to handle pluggable facets here */
+        if(facet != null && facet.equals(HEADER_FACET_NAME))
+        {
+            addStateAttribute(internalGetThState(), name, value, facet);
+        }
+        else if(facet == null || !facet.equals(DEFAULT_FACET_NAME))
+        {
+            addStateAttribute(internalGetHtmlState(), name, value, facet);
+        }
+        else
+        {
             String s = Bundle.getString("Tags_AttributeFacetNotSupported", new 
Object[]{facet});
             throw new RuntimeException(s);
         }
-
-        if(_attributeList == null)
-            _attributeList = new ArrayList();
-
-        _attributeList.add(new AttributeStruct(name, value, facet));
     }
 
-    protected void applyAttributes()
-        throws JspException
+    private void addStateAttribute(AbstractHtmlState state, String name, 
String value, String facet)
     {
-        assert getColumnModel() != null;
-        assert getColumnModel() instanceof AbstractHtmlColumnModel;
+        boolean error = false;
 
-        super.applyAttributes();
-
-        AbstractHtmlColumnModel htmlColumn = 
(AbstractHtmlColumnModel)getColumnModel();
+        // validate the name attribute, in the case of an error simply return.
+        if (name == null || name.length() <= 0) {
+            String s = Bundle.getString("Tags_AttributeNameNotSet");
+            throw new RuntimeException(s);
+        }
 
-        htmlColumn.setOnClick(_onClick);
-        htmlColumn.setOnDblClick(_onDblClick);
-        htmlColumn.setOnKeyDown(_onKeyDown);
-        htmlColumn.setOnKeyUp(_onKeyUp);
-        htmlColumn.setOnKeyPress(_onKeyPress);
-        htmlColumn.setOnMouseDown(_onMouseDown);
-        htmlColumn.setOnMouseUp(_onMouseUp);
-        htmlColumn.setOnMouseMove(_onMouseMove);
-        htmlColumn.setOnMouseOut(_onMouseOut);
-        htmlColumn.setOnMouseOver(_onMouseOver);
-        htmlColumn.setStyle(_style);
-        htmlColumn.setStyleClass(_styleClass);
-        htmlColumn.setTitle(_title);
+        // it's not legal to set the id or name attributes this way
+        if (name != null && (name.equals(HtmlConstants.ID) || 
name.equals(HtmlConstants.NAME))) {
+            String s = Bundle.getString("Tags_AttributeMayNotBeSet", new 
Object[]{name});
+            throw new RuntimeException(s);
+        }
+        if (error)
+            return;
 
-        if(_attributeList != null)
+        // if there is a style or class we will let them override the base
+        if (name.equals(HtmlConstants.CLASS))
+        {
+            state.styleClass = value;
+            return;
+        }
+        else if (name.equals(HtmlConstants.STYLE))
         {
-            Iterator iterator = _attributeList.iterator();
-            while(iterator.hasNext())
-            {
-                AttributeStruct struct = (AttributeStruct)iterator.next();
-                htmlColumn.setAttribute(struct.name, struct.value, 
struct.facet);
-            }
+            state.style = value;
+            return;
         }
+        state.registerAttribute(AbstractHtmlState.ATTR_GENERAL, name, value);
     }
 
-    private static class AttributeStruct
+    protected abstract AbstractHtmlState internalGetHtmlState();
+
+    private final ThTag.State internalGetThState()
     {
-        String name;
-        String value;
-        String facet;
+        return _thState;
+    }
 
-        AttributeStruct(String name, String value, String facet)
-        {
-            this.name = name;
-            this.value = value;
-            this.facet = facet;
-        }
+    private final TdTag.State internalGetTdState()
+    {
+        return _tdState;
     }
+
+    public void openHeaderCell(AbstractRenderAppender appender) {
+        DataGridModel dgm = DataGridUtil.getDataGridModel(getJspContext());
+         if (_thState.styleClass == null)
+             _thState.styleClass = dgm.getCssPolicy().getHeaderCellClass();
+
+         dgm.getTableRenderer().openHeaderCell(_thState, appender);
+     }
+
+     public void closeHeaderCell(AbstractRenderAppender appender) {
+         
DataGridUtil.getDataGridModel(getJspContext()).getTableRenderer().closeHeaderCell(appender);
+     }
+
+     public void openDataCell(AbstractRenderAppender appender) {
+         DataGridModel dgm = DataGridUtil.getDataGridModel(getJspContext());
+         if(_tdState.styleClass == null)
+             _tdState.styleClass = dgm.getCssPolicy().getDataCellClass();
+
+         dgm.getTableRenderer().openTableCell(_tdState, appender);
+     }
+
+     public void closeDataCell(AbstractRenderAppender appender) {
+         
DataGridUtil.getDataGridModel(getJspContext()).getTableRenderer().closeTableCell(appender);
+     }
 }

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 Nov 10 12:40:31 2004
@@ -18,92 +18,129 @@
 package org.apache.beehive.netui.tags.databinding.datagrid;
 
 import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.http.HttpServletRequest;
 
-import org.apache.beehive.netui.databinding.datagrid.model.AbstractColumnModel;
-import 
org.apache.beehive.netui.databinding.datagrid.model.impl.AnchorColumnModel;
+import org.apache.beehive.netui.databinding.datagrid.model.DataGridModel;
+import org.apache.beehive.netui.databinding.datagrid.util.JspUtil;
 import org.apache.beehive.netui.tags.html.URLParams;
+import org.apache.beehive.netui.tags.rendering.AnchorTag;
+import org.apache.beehive.netui.tags.rendering.AbstractHtmlState;
+import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender;
+import org.apache.beehive.netui.tags.rendering.SpanTag;
+import org.apache.beehive.netui.tags.rendering.TagRenderingBase;
 import org.apache.beehive.netui.util.logging.Logger;
+import org.apache.beehive.netui.util.ParamHelper;
 
+import java.net.MalformedURLException;
+import java.util.HashMap;
 
 /**
- * 
- * @netui:tag name="anchorColumn" description="Renders a column of anchors in 
a NetUI data grid" body-content="scriptless"
- * @netui.tldx:tag whitespace="indent" 
+ * @netui:tag name="anchorColumn"
+ *            description="Renders a column of anchors in a NetUI data grid"
+ *            body-content="scriptless"
+ * @netui.tldx:tag whitespace="indent"
  *                 
renderer="workshop.netui.jspdesigner.tldx.AnchorColumnRenderer"
  */
 public class AnchorColumn
     extends AbstractHtmlColumn
-    implements URLParams
-{
-    private static final Logger _logger = 
Logger.getInstance(AnchorColumn.class);
+    implements URLParams {
 
-    private AnchorColumnModel _column;
+    private static final Logger _logger = 
Logger.getInstance(AnchorColumn.class);
 
     private String _value = null;
     private String _href = null;
-    private String _scope = null;
+    private String _scopeId = null;
     private String _action = null;
+    private HashMap _params = null;
+
+    private AnchorTag.State _anchorState = new AnchorTag.State();
+
+    public String getTagName() {
+        return "AnchorColumn";
+    }
 
     /**
      * @jsptagref.attributedescription The URL that is invoked when the column 
header is clicked.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>string_href</i>
-     *
      * @netui:attribute required="false" rtexprvalue="true"
      */
-    public void setHref(String href) {_href = href;}
+    public void setHref(String href) {
+        _href = href;
+    }
 
     /**
      * @netui:attribute required="false"
-     */ 
-    public void setScope(String scope) {_scope = scope;}
+     */
+    public void setScope(String scope) {
+        _scopeId = scope;
+    }
 
     /**
      * @netui:attribute required="true" rtexprvalue="true"
      */
-    public void setValue(String value) {_value = value;}
+    public void setValue(String value) {
+        _value = value;
+    }
 
     /**
      * @netui:attribute required="false"
      * @netui.tldx:attribute category="general" reftype="netui-action-url"
-     */ 
-    public void setAction(String action) {_action = action;}
+     */
+    public void setAction(String action) {
+        _action = action;
+    }
 
     public void addParameter(String name, Object value)
-        throws JspException
-    {
-        ((AnchorColumnModel)getColumnModel()).addParameter(name, value);
-    }
+            throws JspException {
+        if (_params == null)
+            _params = new HashMap();
 
-    public String getTagName()
-    {
-        return "AnchorColumn";
+        ParamHelper.addParam(_params, name, value);
     }
 
     protected void applyAttributes()
-        throws JspException
-    {
+            throws JspException {
         super.applyAttributes();
 
-        if(_action != null && _href != null)
+        if (_action != null && _href != null)
             throw new JspException("Unable to create AnchorColumnModel.  The 
'action' and 'href' attributes can not both be set.");
-
-        _column.setAction(_action);
-        _column.setHref(_href);
-        _column.setScopeId(_scope);
-        _column.setValue(_value);
     }
 
-    protected void setColumnModel(AbstractColumnModel column)
+    protected AbstractHtmlState internalGetHtmlState()
     {
-        assert column != null : "Can't set a null ColumnModel";
-        assert column instanceof AnchorColumnModel;
-
-        _column = (AnchorColumnModel)column;
+        return _anchorState;
     }
 
-    protected AbstractColumnModel createColumnModel()
-    {
-        return new AnchorColumnModel();
+    protected void renderDataCell(AbstractRenderAppender appender) {
+
+        HttpServletRequest request = 
(HttpServletRequest)((PageContext)getJspContext()).getRequest();
+
+        SpanTag.State spanState = new SpanTag.State();
+        AnchorTag.State anchorState = _anchorState;
+
+        DataGridModel dgm = DataGridUtil.getDataGridModel(getJspContext());
+        assert dgm != null;
+
+        String url = null;
+        try {
+            url = JspUtil.createURL(_href, _action, null, _scopeId, _params, 
dgm.getJspContext());
+        } catch (MalformedURLException mue) {
+            /* todo: real, tag based error reporting */
+            if (_logger.isErrorEnabled())
+                _logger.error("Exception creating URL with href " + _href + " 
action " + _action, mue);
+        }
+
+        anchorState.href = url;
+
+        TagRenderingBase anchorTag = 
TagRenderingBase.Factory.getRendering(TagRenderingBase.ANCHOR_TAG, request);
+        TagRenderingBase spanTag = 
TagRenderingBase.Factory.getRendering(TagRenderingBase.SPAN_TAG, request);
+
+        anchorTag.doStartTag(appender, anchorState);
+        spanTag.doStartTag(appender, spanState);
+        appender.append(_value);
+        spanTag.doEndTag(appender);
+        anchorTag.doEndTag(appender);
     }
 }

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Caption.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Caption.java
  (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Caption.java
  Wed Nov 10 12:40:31 2004
@@ -19,24 +19,23 @@
 
 import java.io.IOException;
 import java.io.StringWriter;
-import javax.servlet.jsp.tagext.JspTag;
 import javax.servlet.jsp.tagext.JspFragment;
 import javax.servlet.jsp.JspException;
 
 import org.apache.beehive.netui.tags.AbstractSimpleTag;
-import org.apache.beehive.netui.util.logging.Logger;
+import org.apache.beehive.netui.databinding.datagrid.model.DataGridModel;
 
 /**
  *
- * @netui:tag name="caption" body-content="scriptless" description="Renders a 
caption into a NetUI data grid"
+ * @netui:tag name="caption"
+ *            body-content="scriptless"
+ *            description="Renders a caption into a NetUI data grid"
  * @netui.tldx:tag whitespace="indent"
  *                 renderer=""
  */
 public class Caption
     extends AbstractSimpleTag
 {
-    private DataGrid _dataGrid = null;
-
     public String getTagName()
     {
         return "Caption";
@@ -45,8 +44,10 @@
     public void doTag()
         throws IOException, JspException
     {
-        DataGrid grid = getDataGrid();
-        if(grid.getRenderState() == DataGrid.CAPTION_RENDER_STATE)
+        DataGridModel dgm = DataGridUtil.getDataGridModel(getJspContext());
+        assert dgm != null;
+
+        if(dgm.getRenderState() == DataGridModel.CAPTION_RENDER_STATE)
         {
             JspFragment fragment = getJspBody();
             StringWriter sw = new StringWriter();
@@ -59,17 +60,5 @@
                 getJspContext().getOut().write(bodyContent);
             }
         }
-    }
-
-    protected DataGrid getDataGrid()
-        throws JspException
-    {
-        if(_dataGrid != null)
-            return _dataGrid;
-
-        JspTag parent = getParent();
-        if(!(parent instanceof DataGrid))
-            throw new JspException("The Columns tag must be contained inside 
of a DataGrid tag.");
-        else return (_dataGrid = (DataGrid)parent);
     }
 }

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 Nov 10 12:40:31 2004
@@ -20,15 +20,17 @@
 import java.io.IOException;
 import java.io.StringWriter;
 import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspContext;
 import javax.servlet.jsp.tagext.JspFragment;
-import javax.servlet.jsp.tagext.JspTag;
 
-import org.apache.beehive.netui.databinding.datagrid.model.AbstractColumnModel;
+import org.apache.beehive.netui.databinding.datagrid.model.ColumnsModel;
 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.ColumnModel;
 import org.apache.beehive.netui.tags.AbstractSimpleTag;
 import org.apache.beehive.netui.tags.rendering.StringBuilderRenderAppender;
 import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender;
-import org.apache.beehive.netui.util.logging.Logger;
+import org.apache.beehive.netui.tags.rendering.TrTag;
 
 /**
  *
@@ -42,123 +44,91 @@
 public class Columns
     extends AbstractSimpleTag
 {
-    private static final Logger _logger = Logger.getInstance(DataGrid.class);
+    static final String COLUMNS_MODEL_KEY = "columns";
 
-    public static final String COLUMN_MODEL_KEY = "column";
-
-    private int _renderState = AbstractColumnModel.NO_RENDER_STATE;
-    private Boolean _sortable = null;
-    private Boolean _filterable = null;
-    private String _sortAction = null;
-    private String _filterAction = null;
-
-    private DataGrid _grid = null;
-    private DataGridModel _gridModel = null;
-
-    public String getTagName() {return "Columns";}
+    public String getTagName() {
+        return "Columns";
+    }
     
     public void doTag()
         throws IOException, JspException
     {
-        JspTag parent = getParent();
-        if(!(parent instanceof DataGrid))
-            throw new JspException("The Columns tag must be contained inside 
of a DataGrid tag.");
-
-        _grid = (DataGrid)parent;
-
-        Object model = 
getJspContext().getAttribute(DataGrid.DATA_GRID_MODEL_KEY);
-        if(!(model instanceof DataGridModel))
-            throw new JspException("Could not find the DataGridModel in the 
JspContext under key: " + DataGrid.DATA_GRID_MODEL_KEY);
-
-        _gridModel = (DataGridModel)model;
-
-        int gridRenderState = _grid.getRenderState();
-        JspFragment fragment = getJspBody();
-        StringWriter sw = new StringWriter();
-
-        if (gridRenderState == DataGrid.START_RENDER_STATE)
-        {
-            // 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
-            if(fragment != null)
-                fragment.invoke(sw);
-        }
-        else if(gridRenderState == DataGrid.CAPTION_RENDER_STATE ||
-                gridRenderState == DataGrid.FOOTER_RENDER_STATE)
+        JspContext jspContext = getJspContext();
+        DataGridModel dataGridModel = 
DataGridUtil.getDataGridModel(jspContext);
+        int gridRenderState = dataGridModel.getRenderState();
+
+        if(gridRenderState == DataGridModel.CAPTION_RENDER_STATE ||
+                gridRenderState == DataGridModel.FOOTER_RENDER_STATE ||
+                gridRenderState == DataGridModel.START_RENDER_STATE)
         {
             return;
         }
-        else if(gridRenderState == DataGrid.GRID_RENDER_STATE)
+        else if(gridRenderState == DataGridModel.GRID_RENDER_STATE)
         {
+            ColumnsModel columnsModel = new ColumnsModel();
+            assert columnsModel != null;
+
+            jspContext.setAttribute(COLUMNS_MODEL_KEY, columnsModel);
+
             StringBuilder content = new StringBuilder();
             AbstractRenderAppender appender = new 
StringBuilderRenderAppender(content);
+            JspFragment fragment = getJspBody();
+            StringWriter sw = new StringWriter();
 
             // render header row
-            _gridModel.resetColumnIterator();
-            _renderState = AbstractColumnModel.HEADER_RENDER_STATE;
-            _gridModel.openHeaderRow(appender);
+            columnsModel.setRenderState(ColumnsModel.HEADER_RENDER_STATE);
+            openHeaderRow(appender, dataGridModel);
             fragment.invoke(sw);
             content.append(sw.toString());
-            _gridModel.closeHeaderRow(appender);
+            closeHeaderRow(appender, dataGridModel);
 
             // render data rows
-            _renderState = AbstractColumnModel.DATA_RENDER_STATE;
-            while(_gridModel.hasNextDataItem())
+            columnsModel.setRenderState(ColumnsModel.DATA_RENDER_STATE);
+            while(dataGridModel.hasNextDataItem())
             {
                 sw = new StringWriter();
-                _gridModel.resetColumnIterator();
-                _gridModel.openDataRow(appender);
-                _gridModel.nextDataItem();
+                openDataRow(appender, dataGridModel);
+                dataGridModel.nextDataItem();
                 fragment.invoke(sw);
                 content.append(sw.toString());
-                _gridModel.closeDataRow(appender);
+                closeDataRow(appender, dataGridModel);
             }
 
-            _renderState = AbstractColumnModel.NO_RENDER_STATE;
+            columnsModel.setRenderState(ColumnsModel.NO_RENDER_STATE);
 
-            getJspContext().getOut().write(content.toString());
+            jspContext.removeAttribute(COLUMNS_MODEL_KEY);
+            jspContext.getOut().write(content.toString());
         }
     }
 
-    public int getRenderState()
+    public final void openHeaderRow(AbstractRenderAppender appender, 
DataGridModel dataGridModel)
     {
-        return _renderState;
+        StylePolicy stylePolicy = dataGridModel.getCssPolicy();
+        TrTag.State state = new TrTag.State();
+        state.styleClass = stylePolicy.getHeaderRowClass();
+
+        dataGridModel.getTableRenderer().openHeaderRow(state, appender);
     }
 
-    public void addColumn(AbstractColumnModel cm)
+    public void closeHeaderRow(AbstractRenderAppender appender, DataGridModel 
dataGridModel)
     {
-        if(_logger.isDebugEnabled())
-            _logger.debug("adding column of type " +
-                    (cm != null ? cm.getClass().getName() : null) + " with 
identity " +
-                    System.identityHashCode(cm));
-
-        if(_sortAction != null)
-            cm.setSortUri(_sortAction);
-
-        if(_filterAction != null)
-            cm.setFilterUri(_filterAction);
-
-        if(cm.isSortable() == null && _sortable != null)
-            cm.setSortable(_sortable);
-
-        if(cm.isFilterable() == null && _filterable != null)
-            cm.setFilterable(_filterable);
-
-        if(_logger.isDebugEnabled())
-            _logger.debug("add a column: " + cm + " total columns: " +
-                          (_gridModel.getColumns() != null ? 
_gridModel.getColumns().size() : 0));
-
-        _gridModel.addColumn(cm);
+        dataGridModel.getTableRenderer().closeHeaderRow(appender);
     }
 
-    public void loadNextColumn()
+    public void openDataRow(AbstractRenderAppender appender, DataGridModel 
dataGridModel)
     {
-        AbstractColumnModel cm = _gridModel.getNextColumnModel();
-        getJspContext().setAttribute(COLUMN_MODEL_KEY, cm);
+        TrTag.State state = new TrTag.State();
+        int index = dataGridModel.getCurrentIndex();
+        StylePolicy stylePolicy = dataGridModel.getCssPolicy();
+        if(index % 2 == 0)
+            state.styleClass = stylePolicy.getRowClass();
+        else state.styleClass = stylePolicy.getAltRowClass();
+
+        dataGridModel.getTableRenderer().openTableRow(state, appender);
     }
 
-    public void unloadColumn()
+    public void closeDataRow(AbstractRenderAppender appender, DataGridModel 
dataGridModel)
     {
-        getJspContext().removeAttribute(COLUMN_MODEL_KEY);
+        dataGridModel.getTableRenderer().closeTableRow(appender);
     }
 }

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/ConfigurePager.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/ConfigurePager.java
   (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/ConfigurePager.java
   Wed Nov 10 12:40:31 2004
@@ -92,7 +92,7 @@
     {
         if(_pageSize != null)
         {
-            DataGridModel dgm = 
(DataGridModel)getJspContext().getAttribute("dataGrid");
+            DataGridModel dgm = DataGridUtil.getDataGridModel(getJspContext());
             assert dgm != null;
 
             PagerModel pm = dgm.getPagerModel();

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 Nov 10 12:40:31 2004
@@ -29,12 +29,15 @@
 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.util.PagedDataSet;
+import org.apache.beehive.netui.databinding.datagrid.rendering.TableRenderer;
 import org.apache.beehive.netui.script.common.IDataAccessProvider;
 import org.apache.beehive.netui.script.common.DataAccessProviderStack;
 import org.apache.beehive.netui.tags.ExpressionHandling;
 import org.apache.beehive.netui.tags.AbstractSimpleTag;
 import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender;
 import org.apache.beehive.netui.tags.rendering.StringBuilderRenderAppender;
+import org.apache.beehive.netui.tags.rendering.TableTag;
+import org.apache.beehive.netui.tags.rendering.TrTag;
 import org.apache.beehive.netui.util.logging.Logger;
 import org.apache.beehive.netui.util.iterator.IteratorFactory;
 
@@ -51,29 +54,19 @@
 
     private static final Logger _logger = Logger.getInstance(DataGrid.class);
 
-    private static final StylePolicy DEFAULT_STYLE_POLICY = new 
DefaultStylePolicy();
-    private static final StylePolicy EMPTY_STYLE_POLICY = new 
EmptyStylePolicy();
+    static final String DATA_GRID_MODEL_KEY = "dataGrid";
 
     private static final String DEFAULT_STYLE_POLICY_VALUE = "default";
     private static final String NO_STYLE_POLICY_VALUE = "none";
-
-    public static final String DATA_GRID_MODEL_KEY = "dataGrid";
-
-    public static final int START_RENDER_STATE = 10;
-    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;
-
-    private DataGridModel _gridModel = null;
+    private static final StylePolicy DEFAULT_STYLE_POLICY = new 
DefaultStylePolicy();
+    private static final StylePolicy EMPTY_STYLE_POLICY = new 
EmptyStylePolicy();
 
     private boolean _disableDefaultPager = false;
-    private int _renderState = START_RENDER_STATE;
-
     private String _name = null;
     private String _cssClassPolicy = DEFAULT_STYLE_POLICY_VALUE;
     private String _cssClassPrefix = null;
     private String _dataSource = null;
+    private DataGridModel _gridModel = null;
 
     public String getTagName() {
         return "DataGrid";
@@ -118,8 +111,6 @@
     public void doTag()
         throws JspException, IOException {
 
-        _gridModel = new DataGridModel(getJspContext(), _name);
-
         // create the dataSource expression
         String dataSource = getDataSource();
 
@@ -130,8 +121,6 @@
         Iterator iterator = IteratorFactory.createIterator(ds);
         PagedDataSet dataSet = new PagedDataSet(dataSource, iterator);
 
-        _gridModel.setDataSet(dataSet);
-
         StylePolicy cssPolicy = null;
         if (_cssClassPrefix != null)
             cssPolicy = new DefaultStylePolicy(_cssClassPrefix);
@@ -140,17 +129,18 @@
         else if (_cssClassPolicy.equals(NO_STYLE_POLICY_VALUE))
             cssPolicy = EMPTY_STYLE_POLICY;
 
-        _gridModel.setCssPolicy(cssPolicy);
+        _gridModel = new DataGridModel(getJspContext(), _name, dataSet);
 
-        _renderState = START_RENDER_STATE;
-
-        // todo: optimize -- this doesn't need to happen when the data set is 
empty
+        /* todo: optimize -- this doesn't need to happen when the data set is 
empty */
         DataAccessProviderStack.addDataAccessProvider(this, getJspContext());
         getJspContext().setAttribute(DATA_GRID_MODEL_KEY, _gridModel);
 
         JspFragment fragment = getJspBody();
         if (fragment == null)
+        {
+            cleanup();
             return;
+        }
 
         StringBuilder builder = new StringBuilder(2048);
         AbstractRenderAppender appender = new 
StringBuilderRenderAppender(builder);
@@ -159,60 +149,58 @@
         fragment.invoke(sw);
 
         _gridModel.initialize();
+        _gridModel.setCssPolicy(cssPolicy);
+        _gridModel.setRenderState(DataGridModel.START_RENDER_STATE);
+
+        TableRenderer tableRenderer = _gridModel.getTableRenderer();
 
         if (!_disableDefaultPager)
             _gridModel.renderPager(appender);
 
-        _gridModel.openTable(appender);
+        openTable(appender, cssPolicy, tableRenderer);
 
         /* render the caption */
-        _renderState = CAPTION_RENDER_STATE;
+        _gridModel.setRenderState(DataGridModel.CAPTION_RENDER_STATE);
         sw = new StringWriter();
         fragment.invoke(sw);
         String caption = sw.toString();
         if (caption != null && !caption.trim().equals("")) {
-            _gridModel.openCaption(appender);
+            openCaption(appender, tableRenderer);
             appender.append(caption);
-            _gridModel.closeCaption(appender);
+            closeCaption(appender, tableRenderer);
         }
 
         /* render the grid rows (header and data) */
-        _renderState = GRID_RENDER_STATE;
+        _gridModel.setRenderState(DataGridModel.GRID_RENDER_STATE);
         sw = new StringWriter();
         fragment.invoke(sw);
         appender.append(sw.toString());
 
         /* render the footer */
-        _renderState = FOOTER_RENDER_STATE;
+        _gridModel.setRenderState(DataGridModel.FOOTER_RENDER_STATE);
         sw = new StringWriter();
         fragment.invoke(sw);
         String footer = sw.toString();
         String trimmed = footer.trim();
         if (footer != null && !trimmed.trim().equals("")) {
-            _gridModel.openFooterRow(appender);
+            openFooterRow(appender, cssPolicy, tableRenderer);
             appender.append(footer);
-            _gridModel.closeFooterRow(appender);
+            closeFooterRow(appender, tableRenderer);
         }
 
-        _gridModel.closeTable(appender);
-        _gridModel.uninitialize();
+        closeTable(appender, tableRenderer);
 
-        _renderState = END_RENDER_STATE;
+        _gridModel.setRenderState(DataGridModel.END_RENDER_STATE);
 
         write(builder.toString());
 
-        DataAccessProviderStack.removeDataAccessProvider(getJspContext());
-        getJspContext().removeAttribute(DATA_GRID_MODEL_KEY);
+        cleanup();
     }
 
-    /* ===========================================================
-     *
-     * Cooperative tag set methods
-     *
-     * ===========================================================
-     */
-    public int getRenderState() {
-        return _renderState;
+    private void cleanup()
+    {
+        DataAccessProviderStack.removeDataAccessProvider(getJspContext());
+        getJspContext().removeAttribute(DATA_GRID_MODEL_KEY);
     }
 
     /* ===========================================================
@@ -240,7 +228,42 @@
     }
 
     public IDataAccessProvider getProviderParent() {
-        IDataAccessProvider dap = (IDataAccessProvider) 
SimpleTagSupport.findAncestorWithClass(this, IDataAccessProvider.class);
+        IDataAccessProvider dap =
+                (IDataAccessProvider) 
SimpleTagSupport.findAncestorWithClass(this, IDataAccessProvider.class);
         return dap;
+    }
+
+    private void openTable(AbstractRenderAppender appender, StylePolicy 
cssPolicy, TableRenderer tableRenderer)
+    {
+        TableTag.State state = new TableTag.State();
+        state.styleClass = cssPolicy.getTableClass();
+        tableRenderer.openTable(state, appender);
+    }
+
+    private void closeTable(AbstractRenderAppender appender, TableRenderer 
tableRenderer)
+    {
+        tableRenderer.closeTable(appender);
+        appender.append("\n");
+    }
+
+    private void openCaption(AbstractRenderAppender appender, TableRenderer 
tableRenderer) {
+        tableRenderer.openCaption(appender);
+    }
+
+    private void closeCaption(AbstractRenderAppender appender, TableRenderer 
tableRenderer) {
+        tableRenderer.closeCaption(appender);
+    }
+
+    public void openFooterRow(AbstractRenderAppender appender, StylePolicy 
stylePolicy, TableRenderer tableRenderer)
+    {
+        TrTag.State state = new TrTag.State();
+        state.styleClass = stylePolicy.getFooterRowClass();
+
+        tableRenderer.openFooterRow(state, appender);
+    }
+
+    public void closeFooterRow(AbstractRenderAppender appender, TableRenderer 
tableRenderer)
+    {
+        tableRenderer.closeFooterRow(appender);
     }
 }

Added: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/DataGridUtil.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/DataGridUtil.java
     Wed Nov 10 12:40:31 2004
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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.databinding.datagrid.model.DataGridModel;
+import org.apache.beehive.netui.databinding.datagrid.model.ColumnsModel;
+
+import javax.servlet.jsp.JspContext;
+
+public class DataGridUtil {
+
+    private DataGridUtil() {}
+
+    public static final DataGridModel getDataGridModel(JspContext jspContext)
+    {
+        Object model = jspContext.getAttribute(DataGrid.DATA_GRID_MODEL_KEY);
+
+        assert model != null ? model instanceof DataGridModel : true;
+
+        return (DataGridModel)model;
+    }
+
+    public static final ColumnsModel getColumnsModel(JspContext jspContext)
+    {
+        Object model = jspContext.getAttribute(Columns.COLUMNS_MODEL_KEY);
+
+        assert model != null ? model instanceof ColumnsModel : true;
+
+        return (ColumnsModel)model;
+    }
+}

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Footer.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Footer.java
   (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Footer.java
   Wed Nov 10 12:40:31 2004
@@ -20,22 +20,22 @@
 import java.io.IOException;
 import java.io.StringWriter;
 
-import javax.servlet.jsp.tagext.JspTag;
 import javax.servlet.jsp.tagext.JspFragment;
 import javax.servlet.jsp.JspException;
 
 import org.apache.beehive.netui.tags.AbstractSimpleTag;
+import org.apache.beehive.netui.databinding.datagrid.model.DataGridModel;
 
 /**
- * @netui:tag name="footer" description="Renders a footer into a NetUI data 
grid" body-content="scriptless"
+ * @netui:tag name="footer"
+ *            description="Renders a footer into a NetUI data grid"
+ *            body-content="scriptless"
  * @netui.tldx:tag whitespace="indent"
  *                 renderer=""*
  */
 public class Footer
     extends AbstractSimpleTag
 {
-    private DataGrid _dataGrid = null;
-
     public String getTagName()
     {
         return "Footer";
@@ -44,7 +44,10 @@
     public void doTag()
         throws IOException, JspException
     {
-        if(getDataGrid().getRenderState() == DataGrid.FOOTER_RENDER_STATE)
+        DataGridModel dgm = DataGridUtil.getDataGridModel(getJspContext());
+        assert dgm != null;
+
+        if(dgm.getRenderState() == DataGridModel.FOOTER_RENDER_STATE)
         {
             JspFragment fragment = getJspBody();
             StringWriter sw = new StringWriter();
@@ -57,17 +60,5 @@
                 getJspContext().getOut().write(bodyContent);
             }
         }
-    }
-
-    protected DataGrid getDataGrid()
-        throws JspException
-    {
-        if(_dataGrid != null)
-            return _dataGrid;
-
-        JspTag parent = getParent();
-        if(!(parent instanceof DataGrid))
-            throw new JspException("The Columns tag must be contained inside 
of a DataGrid tag.");
-        else return (_dataGrid = (DataGrid)parent);
     }
 }

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 Nov 10 12:40:31 2004
@@ -17,11 +17,14 @@
  */
 package org.apache.beehive.netui.tags.databinding.datagrid;
 
-import 
org.apache.beehive.netui.databinding.datagrid.model.impl.ImageColumnModel;
-import org.apache.beehive.netui.databinding.datagrid.model.AbstractColumnModel;
-import org.apache.beehive.netui.util.logging.Logger;
+import org.apache.beehive.netui.tags.rendering.AbstractHtmlState;
+import org.apache.beehive.netui.tags.rendering.ImageTag;
+import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender;
+import org.apache.beehive.netui.tags.rendering.TagRenderingBase;
+import org.apache.beehive.netui.tags.html.HtmlConstants;
 
-import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.http.HttpServletRequest;
 
 /**
  * 
@@ -32,96 +35,94 @@
 public class ImageColumn
     extends AbstractHtmlColumn
 {
-    private ImageColumnModel _column;
-    private String _src = null;
-    private String _align = null;
-    private String _hspace = null;
-    private String _vspace = null;
-    private String _border = null;
-    private String _height = null;
-    private String _width = null;
+    private ImageTag.State _imageState = null;
 
     /**
      * @jsptagref.attributedescription The source of the image to display.
      * @jsptagref.databindable Read Only
      * @jsptagref.attributesyntaxvalue <i>literal_or_expression_src</i>
-     *
      * @netui:attribute required="true" rtexprvalue="true"
      * @netui.tldx:attribute 
propertyclass="workshop.jspdesigner.properties.URIPropertyClass"  
reftype="img-url"
      */
-    public void setSrc(String src) {_src = src;}
+    public void setSrc(String src) {
+        internalGetImageState().src = src;
+    }
 
     /**
      * @netui:attribute required="false" rtexprvalue="true"
      */
-    public void setAlign(String align) {_align = align;}
+    public void setAlign(String align) {
+        
internalGetImageState().registerAttribute(AbstractHtmlState.ATTR_GENERAL, 
HtmlConstants.ALIGN, align);
+    }
 
     /**
      * @netui:attribute required="false" rtexprvalue="true"
      */
-    public void setHspace(String hspace) {_hspace = hspace;}
+    public void setHspace(String hspace) {
+        
internalGetImageState().registerAttribute(AbstractHtmlState.ATTR_GENERAL, 
HtmlConstants.HSPACE, hspace);
+    }
 
     /**
      * @jsptagref.attributedescription Integer. The width of the border around 
the image.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>integer_border</i>
-     *
      * @netui:attribute required="false" rtexprvalue="true"
      */
-    public void setVspace(String vspace) {_vspace = vspace;}
+    public void setVspace(String vspace) {
+        
internalGetImageState().registerAttribute(AbstractHtmlState.ATTR_GENERAL, 
HtmlConstants.VSPACE, vspace);
+    }
 
     /**
      * @netui:attribute required="false" rtexprvalue="true"
      */
-    public void setBorder(String border) {_border = border;}
+    public void setBorder(String border) {
+        
internalGetImageState().registerAttribute(AbstractHtmlState.ATTR_GENERAL, 
HtmlConstants.BORDER, border);
+    }
 
     /**
-     * @jsptagref.attributedescription  Integer. The height of the image to be 
displayed in pixels.
+     * @jsptagref.attributedescription Integer. The height of the image to be 
displayed in pixels.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>integer_height</i>
-     *
      * @netui:attribute required="false" rtexprvalue="true"
      */
-    public void setHeight(String height) {_height = height;}
+    public void setHeight(String height) {
+        
internalGetImageState().registerAttribute(AbstractHtmlState.ATTR_GENERAL, 
HtmlConstants.HEIGHT, height);
+    }
 
     /**
      * @jsptagref.attributedescription Integer. The width of the image to be 
displayed in pixels.
      * @jsptagref.databindable false
      * @jsptagref.attributesyntaxvalue <i>integer_width</i>
-     *
      * @netui:attribute required="false" rtexprvalue="true"
      */
-    public void setWidth(String width) {_width = width;}
+    public void setWidth(String width) {
+        
internalGetImageState().registerAttribute(AbstractHtmlState.ATTR_GENERAL, 
HtmlConstants.WIDTH, width);
+    }
 
     public String getTagName()
     {
         return "ImageColumn";
     }
 
-    protected void applyAttributes()
-        throws JspException
+    public void renderDataCell(AbstractRenderAppender appender)
     {
-        super.applyAttributes();
+        HttpServletRequest request = 
(HttpServletRequest)((PageContext)getJspContext()).getRequest();
 
-        _column.setSrc(_src);
-        _column.setBorder(_border);
-        _column.setHeight(_height);
-        _column.setWidth(_width);
-        _column.setHspace(_hspace);
-        _column.setVspace(_vspace);
-        _column.setAlign(_align);
+        TagRenderingBase br = 
TagRenderingBase.Factory.getRendering(TagRenderingBase.IMAGE_TAG, request);
+        br.doStartTag(appender, _imageState);
+        br.doEndTag(appender);
     }
 
-    protected void setColumnModel(AbstractColumnModel column)
-    {
-        assert column != null : "Can't set a null ColumnModel";
-        assert column instanceof ImageColumnModel;
-        _column = (ImageColumnModel)column;
+    private ImageTag.State internalGetImageState() {
+        if(_imageState == null)
+            _imageState = new ImageTag.State();
+
+        return _imageState;
     }
 
-    protected AbstractColumnModel createColumnModel()
+    protected AbstractHtmlState internalGetHtmlState()
     {
-        return new ImageColumnModel();
+        return internalGetImageState();
     }
 }
 

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 Nov 10 12:40:31 2004
@@ -17,53 +17,62 @@
  */
 package org.apache.beehive.netui.tags.databinding.datagrid;
 
-import org.apache.beehive.netui.databinding.datagrid.model.AbstractColumnModel;
-import 
org.apache.beehive.netui.databinding.datagrid.model.impl.LiteralColumnModel;
-import org.apache.beehive.netui.util.logging.Logger;
+import org.apache.beehive.netui.tags.rendering.SpanTag;
+import org.apache.beehive.netui.tags.rendering.AbstractHtmlState;
+import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender;
+import org.apache.beehive.netui.tags.rendering.TagRenderingBase;
 
 import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.http.HttpServletRequest;
 
 /**
  *
- * @netui:tag name="literalColumn" description="Renders a column of data in a 
NetUI grid" body-content="scriptless"
+ * @netui:tag name="literalColumn"
+ *            description="Renders a column of data in a NetUI grid"
+ *            body-content="scriptless"
  * @netui.tldx:tag whitespace="indent"
  *                 
renderer="workshop.netui.jspdesigner.tldx.LiteralColumnRenderer"
  */
 public class LiteralColumn
     extends AbstractHtmlColumn
 {
-    private static final Logger logger = 
Logger.getInstance(LiteralColumn.class);
+    private static final SpanTag.State DEFAULT_SPAN_STATE = new 
SpanTag.State();
 
     private String _value = null;
-    private LiteralColumnModel _column = null;
+    private SpanTag.State _spanState = new SpanTag.State();
+
+    public String getTagName() {
+        return "LiteralColumnModel";
+    }
 
     /**
      * @netui:attribute required="true" rtexprvalue="true"
      */
-    public void setValue(String value) {_value = value;}
-
-    public String getTagName()
-    {
-        return "LiteralColumnModel";
+    public void setValue(String value) {
+        _value = value;
     }
 
     protected void applyAttributes()
-        throws JspException
-    {
+        throws JspException {
         super.applyAttributes();
 
-        _column.setValue(_value);
+        /* todo: need to apply the <span> HTML state information to the 
ColumnModel here */
     }
 
-    protected void setColumnModel(AbstractColumnModel column)
-    {
-        assert column instanceof LiteralColumnModel;
-
-        _column = (LiteralColumnModel)column;
+    protected void renderDataCell(AbstractRenderAppender appender) {
+        HttpServletRequest request = 
(HttpServletRequest)((PageContext)getJspContext()).getRequest();
+        TagRenderingBase span = 
TagRenderingBase.Factory.getRendering(TagRenderingBase.SPAN_TAG, request);
+
+        String formatted = formatText(_value);
+
+        span.doStartTag(appender, _spanState != null ? _spanState : 
DEFAULT_SPAN_STATE);
+        appender.append(formatted);
+        span.doEndTag(appender);
     }
 
-    protected AbstractColumnModel createColumnModel()
+    protected AbstractHtmlState internalGetHtmlState()
     {
-        return new LiteralColumnModel();
+        return _spanState;
     }
 }

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/pageinput/DeclarePageInput.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/pageinput/DeclarePageInput.java
        (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/pageinput/DeclarePageInput.java
        Wed Nov 10 12:40:31 2004
@@ -17,19 +17,15 @@
  */
 package org.apache.beehive.netui.tags.databinding.pageinput;
 
-// java imports
 import java.util.Map;
-
 import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.http.HttpServletRequest;
 
-// internal imports
-import org.apache.beehive.netui.pageflow.PageFlowUtils;
 import org.apache.beehive.netui.pageflow.internal.InternalUtils;
-import org.apache.beehive.netui.tags.AbstractClassicTag;
 import org.apache.beehive.netui.util.Bundle;
 import org.apache.beehive.netui.util.logging.Logger;
-
-// external imports
+import org.apache.beehive.netui.tags.AbstractSimpleTag;
 
 /**
  * <p>
@@ -52,11 +48,13 @@
  * 
  * <p>
  * On the Controller file, use the <code>addPageInput</code> method 
- * (a method on the [EMAIL PROTECTED] com.bea.wlw.netui.pageflow.Forward 
Forward} class)
+ * (a method on the [EMAIL PROTECTED] 
org.apache.beehive.netui.pageflow.Forward Forward} class)
  * to make the variable available to the &lt;netui-data:declarePageInput> tag.
  * 
- * <pre>    Forward f = new Forward("success");
- *    f.addPageInput("myData", new MyData());</pre>
+ * <pre>
+ *    Forward f = new Forward("success");
+ *    f.addPageInput("myData", new MyData());
+ * </pre>
  * 
  * Then, on the JSP page, declare the variable with the 
&lt;netui-data:declarePageInput> tag.
  * 
@@ -80,24 +78,6 @@
  * helps to indicate clearly the type of data expected at run time. This 
  * information about the incoming data helps your team understand any 
  * data dependencies a given JSP page may have on the Controller file.</li>
- * <li>At design time each &lt;netui-data:declarePageInput> tag, once added 
- * to a JSP page, enables an additional WebLogic Workshop IDE feature to 
discover properties 
- * about your JSP source code. 
- * <p>For example, the presence of a 
- * &lt;netui-data:declarePageInput> tag on a JSP page causes 
- * the Workshop IDE to display the declared variable 
- * in the Data Palette's "Page Inputs" section.  
- * Once the variable is displayed in the Data Palette, you can (1) drag and 
drop the variable from
- * the Data Palette, and (2) set properties on the variable. Note that the 
Data Palette will not display the following data types:
- *   <p>   
- *   primitive Java types<br>
- *   java.*<br>
- *   javax.*<br>
- *   com.sun.*<br>
- *   org.apache.struts.*<br>
- *   com.bea.*
- *   </p>      
- * </li>
  * </ul>
  * </blockquote>
  * 
@@ -138,14 +118,16 @@
  *    ...
  *    fooBean.foo: &lt;netui:label value="{pageInput.fooBean.foo}" /></pre>
  * 
- * @netui:tag name="declarePageInput" description="Use this tag to declare a 
page input variable that is available in the pageInput databinding context."
+ * @netui:tag name="declarePageInput"
+ *            description="Use this tag to declare a page input variable that 
is available in the pageInput databinding context."
+ *            body-content="scriptless"
  * @netui.tldx:tag requiredchild="#nothing" 
  *                 
renderer="workshop.netui.jspdesigner.tldx.DeclarePageInputRenderer"
  *                 bodycontentpref="empty"
  *                 
expressioninfo="workshop.netui.jspdesigner.tldx.expression.NetuiPageInputExpressionInfo"
  */
 public class DeclarePageInput
-    extends AbstractClassicTag
+    extends AbstractSimpleTag
 {
     private static final Logger logger = 
Logger.getInstance(DeclarePageInput.class);
     private static final String EMPTY_STRING = "";
@@ -155,18 +137,24 @@
     private boolean _required = true;
 
     /**
+     * Get the name of this tag.  This is used to identify the type of this tag
+     * for reporting tag errors.
+     *
+     * @return a constant String representing the name of this tag.
+     */
+    public String getTagName()
+    {
+        return "DeclarePageInput";
+    }
+
+    /**
      * Set the name of a variable that can be referecned using the page 
      * input data binding context.
      *
      * @param name the name of the variable
-     *
-     * @jsptagref.attributedescription
-     * The name of the variable to reference.
-     * 
+     * @jsptagref.attributedescription The name of the variable to reference.
      * @jsptagref.databindable false
-     * 
      * @jsptagref.attributesyntaxvalue <i>string_name</i>
-     *
      * @netui:attribute required="true"
      */
     public void setName(String name)
@@ -175,21 +163,11 @@
     }
 
     /**
-     * Get the name of the variable that can be referenced using the page
-     * input data binding context.
-     */
-    public String getName()
-    {
-        return _name;
-    }
-    
-    /**
      * Set the required attribute.  If a Page Input is required, the tag will 
report an 
      * error if the page input key does not appear in the set of page inputs
      * for a page.
      *
      * @param required whether to require the page input for the page
-     *
      * @netui:attribute required="false"
      */
     public void setRequired(boolean required)
@@ -198,27 +176,13 @@
     }
 
     /**
-     * Get the required attribute that forces a page input to be 
-     * present for a page.
-     */
-    public boolean getRequired()
-    {
-        return _required;
-    }
-
-    /**
      * Set the type of the variable that referenced with the 
      * [EMAIL PROTECTED] #setName} attribute on this tag.
      *
      * @param type the type of the variable that is referenced
-     *
-     * @jsptagref.attributedescription
-     * The expected data type of the variable.
-     * 
+     * @jsptagref.attributedescription The expected data type of the variable.
      * @jsptagref.databindable false
-     * 
      * @jsptagref.attributesyntaxvalue <i>string_type</i>
-     *
      * @netui:attribute required="true"
      * @netui.tldx:attribute extype="java-classname"
      */
@@ -228,40 +192,13 @@
     }
 
     /**
-     * Get the type of the variable that referenced with the 
-     * [EMAIL PROTECTED] #setName} attribute on this tag.
-     */
-    public String getType()
-    {
-        return _type;
-    }
-
-    /**
-     * Get the name of this tag.  This is used to identify the type of this tag
-     * for reporting tag errors.
      *
-     * @return a constant String representing the name of this tag.
-     */
-    public String getTagName() 
-    {
-        return "DeclarePageInput";
-    }
-
-    /**
-     * @return SKIP_BODY as this tag does not evaluate its body
      */
-    public int doStartTag()
-    {
-        return SKIP_BODY;
-    }
-
-    /**
-     * @return EVAL_PAGE as this tag always continues to evaluate the page
-     */
-    public int doEndTag()
+    public void doTag()
         throws JspException
     {
-        if(logger.isDebugEnabled()) logger.debug("Added a page input named \"" 
+ _name + "\" of type \""  + _type + "\"");
+        if(logger.isDebugEnabled())
+            logger.debug("Added a page input named \"" + _name + "\" of type 
\""  + _type + "\"");
 
         if(_name.equals(EMPTY_STRING))
         {
@@ -275,29 +212,19 @@
             registerTagError(msg,null);
         }
 
-        Map actionOutputMap = 
InternalUtils.getPageInputMap(pageContext.getRequest());
-        if(_required && (actionOutputMap == null || 
!actionOutputMap.containsKey(_name)))
-        {
-            String msg = 
Bundle.getErrorString("Tags_DeclarePageInput_Required", new Object[] {_name});
-            registerTagError(msg, null);
+        if(_required) {
+            assert getJspContext() instanceof PageContext;
+            assert ((PageContext)getJspContext()).getRequest() instanceof 
HttpServletRequest;
+
+            HttpServletRequest request = 
(HttpServletRequest)((PageContext)getJspContext()).getRequest();
+            Map actionOutputMap = InternalUtils.getPageInputMap(request);
+            if(actionOutputMap == null || !actionOutputMap.containsKey(_name)) 
{
+                String msg = 
Bundle.getErrorString("Tags_DeclarePageInput_Required", new Object[] {_name});
+                registerTagError(msg, null);
+            }
         }
 
         if(hasErrors())
             reportErrors();
-
-        localRelease();
-
-        return EVAL_PAGE;
-    }
-
-    /**
-     * Reset all of the fields of this tag.
-     */
-    protected void localRelease()
-    {
-        super.localRelease();
-        _type = null;
-        _name = null;
-        _required = false;
     }
-}
+}
\ No newline at end of file

Modified: 
incubator/beehive/trunk/netui/src/util/org/apache/beehive/netui/util/HtmlExceptionFormatter.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/util/org/apache/beehive/netui/util/HtmlExceptionFormatter.java
    (original)
+++ 
incubator/beehive/trunk/netui/src/util/org/apache/beehive/netui/util/HtmlExceptionFormatter.java
    Wed Nov 10 12:40:31 2004
@@ -79,11 +79,13 @@
             buf.append(st);
 
             Throwable rootCause = null;
-            if(hasRootCause(t) && (rootCause = discoverRootCause(t)) != null)
+            Throwable tmp = t;
+            while (hasRootCause(tmp) && (rootCause = discoverRootCause(tmp)) 
!= null)
             {
                 st = addStackTrace(rootCause);
                 buf.append(HTML_LINE_BREAK);
                 buf.append(st);
+                tmp = rootCause;
             }
         }
 

Added: 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/misc/customHeaderStyle.jsp
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/misc/customHeaderStyle.jsp
      Wed Nov 10 12:40:31 2004
@@ -0,0 +1,40 @@
+<%@ 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"%>
+
+<netui:html>
+  <head>
+    <title>CSS Prefix Test</title>
+        <style type="text/css">
+        .foo-datagrid-header {
+            background-color: #5f7797;
+        }
+        .foo-datagrid-even {
+            background-color: #ffffff;
+        }
+        .foo-datagrid-odd {
+            background-color: #bfc4cb;
+        }
+        .custom-header {
+            background-color: #770011;
+        }
+        </style>
+  </head>
+  <netui:body>
+    <p>
+    <%@ include file="../util/portfolioXmlBean.jsp" %>
+    <br/>
+    <netui-data:dataGrid dataSource="pageScope.stocks" name="portfolio" 
cssClassPrefix="foo" >
+        <netui-data:columns>
+            <netui-data:literalColumn headerStyleClass="custom-header" 
headerText="Symbol" value="${container.item.symbol}"/>
+            <netui-data:literalColumn 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>
+    </p>
+  </netui:body>
+</netui:html>
\ No newline at end of file

Modified: 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/model/index.jsp
==============================================================================
--- 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/model/index.jsp
 (original)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/model/index.jsp
 Wed Nov 10 12:40:31 2004
@@ -15,14 +15,12 @@
         <netui-data:columns>
             <netui-data:literalColumn headerText="Symbol" 
value="${container.item.symbol}">
               <netuitestutil:assert test="${column != null}" 
failureMessage="Column Model was not found in the PageContext"/>
-              <netuitestutil:assert test="${column.headerText == 'Symbol'}" 
failureMessage="Column Model returned invalid header text"/>
             </netui-data:literalColumn>
             <netui-data:literalColumn headerText="Price" 
value="${container.item.price}">
               <netuitestutil:assert test="${column != null}" 
failureMessage="Column Model was not found in the PageContext"/>
-              <netuitestutil:assert test="${column.headerText == 'Price'}" 
failureMessage="Column Model returned invalid header text"/>
             </netui-data:literalColumn>
             <netui-data:anchorColumn headerText="Web" 
href="${container.item.web}" value="${container.item.name}">
-              <netuitestutil:assert test="${column.headerText == 'Web'}" 
failureMessage="Column Model returned invalid header text"/>
+              <netuitestutil:assert test="${column != null}" 
failureMessage="Column Model was not found in the PageContext"/>
               <netui:parameter name="rowid" value="${container.index}"/>
               <netui:parameter name="symbol" value="${container.item.symbol}"/>
             </netui-data:anchorColumn>

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 Nov 10 12:40:31 2004
@@ -2183,6 +2183,21 @@
          </features>
       </test>
       <test>
+         <name>DataGridCustomHeaderStyle</name>
+         <description>DataGridCustomHeaderStyle</description>
+         <webapp>coreWeb</webapp>
+         <categories>
+            <category>bvt</category>
+            <category>drt</category>
+            <category>datagrid</category>
+            <category>databinding</category>
+         </categories>
+         <features>
+            <feature>Databinding</feature>
+            <feature>Data Grid</feature>
+         </features>
+      </test>
+      <test>
          <name>DataGridCustomTagAttributes</name>
          <description>DataGridCustomTagAttributes</description>
          <webapp>coreWeb</webapp>

Modified: 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/B40031.xml
==============================================================================
--- 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/B40031.xml    
    (original)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/B40031.xml    
    Wed Nov 10 12:40:31 2004
@@ -1,96 +1,77 @@
 <?xml version="1.0" encoding="UTF-8"?>
-
-<recorderSession 
xmlns="http://beehive.apache.org/netui/tools/testrecorder/2004/session";>
-
-  <sessionName>B40031</sessionName>
-  <tester>Daryl</tester>
-  <startDate>26 Mar 2004, 02:41:34.711 PM MST</startDate>
-  <description>Error in the declarePageInput</description>
-
-  <tests>
-  <test>
-    <testNumber>1</testNumber>
-
-    <request>
-
-      <protocol>HTTP</protocol>
-      <protocolVersion>1.1</protocolVersion>
-      <host>localhost</host>
-      <port>7001</port>
-      <uri>/coreWeb/bugs/b40031/Controller.jpf</uri>
-      <method>GET</method>
-
-      <parameters>
-      </parameters>
-
-      <cookies>
-        <cookie>
-          <name>JSESSIONID</name>
-          
<value>AkiXWtFW8FZqscp1vxbYvVXblDcKjhcMJsDLQQNhnAns9wKYsquu!601497888</value>
-        </cookie>
-      </cookies>
-
-      <headers>
-        <header>
-          <name>Accept</name>
-          <value>image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, 
application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, 
*/*</value>
-        </header>
-        <header>
-          <name>Accept-Encoding</name>
-          <value>gzip, deflate, x-gzip, compress, x-compress</value>
-        </header>
-        <header>
-          <name>Accept-Language</name>
-          <value>en-us</value>
-        </header>
-        <header>
-          <name>Connection</name>
-          <value>Keep-Alive, TE</value>
-        </header>
-        <header>
-          <name>Cookie</name>
-          
<value>JSESSIONID=AkiXWtFW8FZqscp1vxbYvVXblDcKjhcMJsDLQQNhnAns9wKYsquu!601497888</value>
-        </header>
-        <header>
-          <name>Cookie2</name>
-          <value>$Version="1"</value>
-        </header>
-        <header>
-          <name>Host</name>
-          <value>localhost:7001</value>
-        </header>
-        <header>
-          <name>TE</name>
-          <value>trailers, deflate, gzip, compress</value>
-        </header>
-        <header>
-          <name>User-Agent</name>
-          <value>Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 
1.1.4322) RPT-HTTPClient/0.3-3E RPT-HTTPClient/0.3-3E</value>
-        </header>
-        <header>
-          <name>testRecorder.playback.failMode</name>
-          <value>stop</value>
-        </header>
-        <header>
-          <name>testRecorder.playback.testID</name>
-          <value>-67265aa3:fb89054f29:-7871</value>
-        </header>
-        <header>
-          <name>testRecorder.playback.testNumber</name>
-          <value>1</value>
-        </header>
-      </headers>
-
-    </request>
-
-    <response>
-      <statusCode>200</statusCode>
-      <reason></reason>
-      <responseBody><![CDATA[<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.01 
Transitional//EN"
+<ses:recorderSession 
xmlns:ses="http://beehive.apache.org/netui/tools/testrecorder/2004/session";>
+   <ses:sessionName>B40031</ses:sessionName>
+   <ses:tester>Daryl</ses:tester>
+   <ses:startDate>10 Nov 2004, 11:46:10.148 AM MST</ses:startDate>
+   <ses:description>Daryl</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/bugs/b40031/Controller.jpf</ses:uri>
+            <ses:method>GET</ses:method>
+            <ses:parameters/>
+            <ses:cookies>
+               <ses:cookie>
+                  <ses:name>JSESSIONID</ses:name>
+                  <ses:value>95771C6095AA898BFC2967AC2F40F242</ses:value>
+               </ses:cookie>
+            </ses:cookies>
+            <ses:headers>
+               <ses:header>
+                  <ses:name>accept</ses:name>
+                  <ses:value>image/gif, image/x-xbitmap, image/jpeg, 
image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, 
application/msword, */*</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-encoding</ses:name>
+                  <ses:value>gzip, deflate, x-gzip, compress, 
x-compress</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-language</ses:name>
+                  <ses:value>en-us</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>connection</ses:name>
+                  <ses:value>Keep-Alive, TE</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>cookie</ses:name>
+                  <ses:value>$Version=0; 
JSESSIONID=95771C6095AA898BFC2967AC2F40F242; $Path=/coreWeb</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>cookie2</ses:name>
+                  <ses:value>$Version="1"</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>host</ses:name>
+                  <ses:value>localhost:8080</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>te</ses:name>
+                  <ses:value>trailers, deflate, gzip, compress</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>testrecorder.playback.testid</ses:name>
+                  <ses:value>-2478af82:10023cc6796:-7eec</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>user-agent</ses:name>
+                  <ses:value>Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 
5.0; .NET CLR 1.1.4322) RPT-HTTPClient/0.3-3E RPT-HTTPClient/0.3-3E</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>
+    <head>
         <title>
             Web Application Page
         </title>
@@ -99,105 +80,87 @@
         <a href="/coreWeb/bugs/b40031/post.do">Post</a>
     </body>
 
-</html>]]></responseBody>
-
-    </response>
-
-    <testResults>
-      <testStatus>fail</testStatus>
-
-    </testResults>
-  </test>
-  <test>
-    <testNumber>2</testNumber>
-
-    <request>
-
-      <protocol>HTTP</protocol>
-      <protocolVersion>1.1</protocolVersion>
-      <host>localhost</host>
-      <port>7001</port>
-      <uri>/coreWeb/bugs/b40031/post.do</uri>
-      <method>GET</method>
-
-      <parameters>
-      </parameters>
-
-      <cookies>
-        <cookie>
-          <name>JSESSIONID</name>
-          
<value>AkiXWtFW8FZqscp1vxbYvVXblDcKjhcMJsDLQQNhnAns9wKYsquu!601497888</value>
-        </cookie>
-      </cookies>
-
-      <headers>
-        <header>
-          <name>Accept</name>
-          <value>image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, 
application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, 
*/*</value>
-        </header>
-        <header>
-          <name>Accept-Encoding</name>
-          <value>gzip, deflate, x-gzip, compress, x-compress</value>
-        </header>
-        <header>
-          <name>Accept-Language</name>
-          <value>en-us</value>
-        </header>
-        <header>
-          <name>Connection</name>
-          <value>Keep-Alive, TE</value>
-        </header>
-        <header>
-          <name>Cookie</name>
-          
<value>JSESSIONID=AkiXWtFW8FZqscp1vxbYvVXblDcKjhcMJsDLQQNhnAns9wKYsquu!601497888</value>
-        </header>
-        <header>
-          <name>Cookie2</name>
-          <value>$Version="1"</value>
-        </header>
-        <header>
-          <name>Host</name>
-          <value>localhost:7001</value>
-        </header>
-        <header>
-          <name>TE</name>
-          <value>trailers, deflate, gzip, compress</value>
-        </header>
-        <header>
-          <name>User-Agent</name>
-          <value>Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 
1.1.4322) RPT-HTTPClient/0.3-3E RPT-HTTPClient/0.3-3E</value>
-        </header>
-        <header>
-          <name>testRecorder.playback.failMode</name>
-          <value>stop</value>
-        </header>
-        <header>
-          <name>testRecorder.playback.testID</name>
-          <value>-67265aa3:fb89054f29:-7871</value>
-        </header>
-        <header>
-          <name>testRecorder.playback.testNumber</name>
-          <value>2</value>
-        </header>
-      </headers>
-
-    </request>
-
-    <response>
-      <statusCode>200</statusCode>
-      <reason></reason>
-      <responseBody><![CDATA[<span> <table border="1" cellspacing="0" 
style="color:red;background-color:white">
+</html>]]></ses:responseBody>
+         </ses:response>
+         <ses:testResults>
+            <ses:testStatus>pass</ses:testStatus>
+         </ses:testResults>
+      </ses:test>
+      <ses:test>
+         <ses:testNumber>2</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/bugs/b40031/post.do</ses:uri>
+            <ses:method>GET</ses:method>
+            <ses:parameters/>
+            <ses:cookies>
+               <ses:cookie>
+                  <ses:name>JSESSIONID</ses:name>
+                  <ses:value>95771C6095AA898BFC2967AC2F40F242</ses:value>
+               </ses:cookie>
+            </ses:cookies>
+            <ses:headers>
+               <ses:header>
+                  <ses:name>accept</ses:name>
+                  <ses:value>image/gif, image/x-xbitmap, image/jpeg, 
image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, 
application/msword, */*</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-encoding</ses:name>
+                  <ses:value>gzip, deflate, x-gzip, compress, 
x-compress</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-language</ses:name>
+                  <ses:value>en-us</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>connection</ses:name>
+                  <ses:value>Keep-Alive, TE</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>cookie</ses:name>
+                  <ses:value>$Version=0; 
JSESSIONID=95771C6095AA898BFC2967AC2F40F242; $Path=/coreWeb</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>cookie2</ses:name>
+                  <ses:value>$Version="1"</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>host</ses:name>
+                  <ses:value>localhost:8080</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>te</ses:name>
+                  <ses:value>trailers, deflate, gzip, compress</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>testrecorder.playback.testid</ses:name>
+                  <ses:value>-2478af82:10023cc6796:-7eec</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>user-agent</ses:name>
+                  <ses:value>Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 
5.0; .NET CLR 1.1.4322) RPT-HTTPClient/0.3-3E RPT-HTTPClient/0.3-3E</ses:value>
+               </ses:header>
+            </ses:headers>
+         </ses:request>
+         <ses:response>
+            <ses:statusCode>200</ses:statusCode>
+            <ses:reason/>
+            <ses:responseBody><![CDATA[<span> <table border="1" 
cellspacing="0" style="color:red;background-color:white">
  <tr><th colspan="5">Tag Error</th></tr>
  <tr><th>Tag</th><td>DeclarePageInput</td>
- <th>Errors</th><td colspan="2">1</td></tr>
+ <th>Errors</th><td colspan="2">2</td></tr>
  <tr><th>Tag Error</th><th>Message</th><td colspan="3">The name attribute of 
the declarePageInput tag can not be an empty string.</td></tr>
+<tr><th>Tag Error</th><th>Message</th><td colspan="3">The page input "" is 
required for this page and was not found.</td></tr>
 </table></span>
 
 <!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd";>
 <html lang="en">
 
-<head>
+    <head>
         <title>
             Web Application Page
         </title>
@@ -209,21 +172,16 @@
         </p>
     </body>
 
-</html>]]></responseBody>
-
-    </response>
-
-    <testResults>
-      <testStatus>fail</testStatus>
-
-    </testResults>
-  </test>
-
-  </tests>
-
-  <endDate>26 Mar 2004, 02:41:37.996 PM MST</endDate>
-  <sessionStatus>fail</sessionStatus>
-  <testCount>2</testCount>
-  <passedCount>0</passedCount>
-  <failedCount>2</failedCount>
-</recorderSession>
\ No newline at end of file
+</html>]]></ses:responseBody>
+         </ses:response>
+         <ses:testResults>
+            <ses:testStatus>fail</ses:testStatus>
+         </ses:testResults>
+      </ses:test>
+   </ses:tests>
+   <ses:endDate>10 Nov 2004, 11:46:11.880 AM MST</ses:endDate>
+   <ses:sessionStatus>fail</ses:sessionStatus>
+   <ses:testCount>2</ses:testCount>
+   <ses:passedCount>1</ses:passedCount>
+   <ses:failedCount>1</ses:failedCount>
+</ses:recorderSession>
\ No newline at end of file

Added: 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridCustomHeaderStyle.xml
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridCustomHeaderStyle.xml
     Wed Nov 10 12:40:31 2004
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ses:recorderSession 
xmlns:ses="http://beehive.apache.org/netui/tools/testrecorder/2004/session";>
+   <ses:sessionName>DataGridCustomHeaderStyle</ses:sessionName>
+   <ses:tester>ekoneil</ses:tester>
+   <ses:startDate>10 Nov 2004, 12:33:23.512 PM MST</ses:startDate>
+   <ses:description>Test of adding a custom style to a data grid 
header.</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/misc/customHeaderStyle.jsp</ses:uri>
+            <ses:method>GET</ses:method>
+            <ses:parameters/>
+            <ses:cookies>
+               <ses:cookie>
+                  <ses:name>JSESSIONID</ses:name>
+                  <ses:value>E941C3B091C7D4A890BA0DF0FCB63E15</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=E941C3B091C7D4A890BA0DF0FCB63E15</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; 
rv:1.7.3) Gecko/20040913 Firefox/0.10.1</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>CSS Prefix Test</title>
+        <style type="text/css">
+        .foo-datagrid-header {
+            background-color: #5f7797;
+        }
+        .foo-datagrid-even {
+            background-color: #ffffff;
+        }
+        .foo-datagrid-odd {
+            background-color: #bfc4cb;
+        }
+        .custom-header {
+            background-color: #770011;
+        }
+        </style>
+  </head>
+  <body>
+    <p>
+    
+ 
+
+
+    <br/>
+    Page 1 of 1&nbsp;&nbsp;&nbsp;
+<table class="foo-datagrid">
+
+        
+<thead>
+<tr class="foo-datagrid-header">
+            <th class="custom-header">Symbol</th>
+
+
+            <th class="foo-datagrid-header-cell">Price</th>
+
+
+            <th class="foo-datagrid-header-cell">Web</th>
+
+
+        
+</tr></thead>
+
+<tr class="foo-datagrid-even">
+            <td class="foo-datagrid-data-cell"><span>BEAS</span></td>
+
+            <td class="foo-datagrid-data-cell"><span>14.35</span></td>
+
+            <td class="foo-datagrid-data-cell"><a 
href="http://www.bea.com?rowid=1&amp;symbol=BEAS";><span>BEA 
Systems</span></a></td>
+
+        
+</tr>
+<tr class="foo-datagrid-odd">
+            <td class="foo-datagrid-data-cell"><span>CSCO</span></td>
+
+            <td class="foo-datagrid-data-cell"><span>19.42</span></td>
+
+            <td class="foo-datagrid-data-cell"><a 
href="http://www.cisco.com?rowid=2&amp;symbol=CSCO";><span>Cisco 
Systems</span></a></td>
+
+        
+</tr>
+<tr class="foo-datagrid-even">
+            <td class="foo-datagrid-data-cell"><span>GE</span></td>
+
+            <td class="foo-datagrid-data-cell"><span>59.42</span></td>
+
+            <td class="foo-datagrid-data-cell"><a 
href="http://www.ge.com?rowid=3&amp;symbol=GE";><span>General 
Electric</span></a></td>
+
+        
+</tr>
+<tr class="foo-datagrid-odd">
+            <td class="foo-datagrid-data-cell"><span>RHAT</span></td>
+
+            <td class="foo-datagrid-data-cell"><span>18.2</span></td>
+
+            <td class="foo-datagrid-data-cell"><a 
href="http://www.redhat.com?rowid=4&amp;symbol=RHAT";><span>RedHat 
Systems</span></a></td>
+
+        
+</tr>
+<tr class="foo-datagrid-even">
+            <td class="foo-datagrid-data-cell"><span>YHOO</span></td>
+
+            <td class="foo-datagrid-data-cell"><span>48.16</span></td>
+
+            <td class="foo-datagrid-data-cell"><a 
href="http://www.yahoo.com?rowid=5&amp;symbol=YHOO";><span>Yahoo 
Inc</span></a></td>
+
+        
+</tr>
+    </table>
+
+
+    </p>
+  </body>
+
+</html>]]></ses:responseBody>
+         </ses:response>
+      </ses:test>
+   </ses:tests>
+   <ses:endDate>10 Nov 2004, 12:33:27.057 PM MST</ses:endDate>
+   <ses:testCount>1</ses:testCount>
+</ses:recorderSession>
\ No newline at end of file

Reply via email to