Author: ekoneil
Date: Thu Apr 21 08:17:22 2005
New Revision: 164073

URL: http://svn.apache.org/viewcvs?rev=164073&view=rev
Log:
More CellRepeater cleanup.

BB: self
DRT: NetUI pass 
BVt: NetUI pass


Modified:
    
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/cellrepeater/CellRepeater.java

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/cellrepeater/CellRepeater.java
URL: 
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/cellrepeater/CellRepeater.java?rev=164073&r1=164072&r2=164073&view=diff
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/cellrepeater/CellRepeater.java
 (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/cellrepeater/CellRepeater.java
 Thu Apr 21 08:17:22 2005
@@ -36,6 +36,7 @@
 import org.apache.beehive.netui.tags.rendering.TrTag;
 import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender;
 import org.apache.beehive.netui.tags.rendering.StringBuilderRenderAppender;
+import org.apache.beehive.netui.tags.rendering.ConstantRendering;
 import org.apache.beehive.netui.util.Bundle;
 import 
org.apache.beehive.netui.util.exception.LocalizedUnsupportedOperationException;
 import org.apache.beehive.netui.util.internal.InternalStringBuilder;
@@ -105,17 +106,13 @@
  * <p/>
  * <p/>
  * The tag will automatically generate the open and close table, row, and cell
- * tags.  Style attributes may
- * be set using attributes on this tag in order to customize the rendered 
table's final
- * appearance.  The dimensions of the table are specified with
- * the attributes <code>columns</code> and <code>rows</code>.
- * If only one dimension is specified, the other
- * will be inferred by using the size of the given data set.  As a result, the
- * entire dataset will be rendered.  For example,
- * if the <code>columns</code> attribute is set to 4 and the data set has 20 
items,
- * the resulting table will have 5 rows.  If the data set has fewer items than
- * the number of cells that should be rendered, the cells are padded with HTML 
table
- * cells:
+ * tags.  Style attributes may be set using attributes on this tag in order to 
customize
+ * the rendered table's final appearance.  The dimensions of the table are 
specified with
+ * the attributes <code>columns</code> and <code>rows</code>.  If only one 
dimension is specified, the other
+ * will be inferred by using the size of the given data set.  As a result, the 
entire dataset will be rendered.
+ * For example, if the <code>columns</code> attribute is set to 4 and the data 
set has 20 items,
+ * the resulting table will have 5 rows.  If the data set has fewer items than 
the number of cells that should
+ * be rendered, the cells are padded with HTML table cells:
  * </p>
  * <p/>
  * <pre>     &lt;td&gt;&amp;nbsp;&lt;/td&gt;</pre>
@@ -154,33 +151,32 @@
     implements IDataAccessProvider, TryCatchFinally {
 
     private static final Logger LOGGER = 
Logger.getInstance(CellRepeater.class);
-    private static final int DEFAULT_DIMENSION_VALUE = -1;
-    private static final TableTag.State TABLE_STATE = new TableTag.State();
-    private static final TrTag.State TR_STATE = new TrTag.State();
-    private static final TdTag.State TD_STATE = new TdTag.State();
+    private static final int DIMENSION_DEFAULT_VALUE = -1;
+    private static final TableTag.State STATE_TABLE = new TableTag.State();
+    private static final TrTag.State STATE_TR = new TrTag.State();
+    private static final TdTag.State STATE_TD = new TdTag.State();
 
     private boolean _valid = true;
     private boolean _verticalRepeat = false;
-    private int _columns = DEFAULT_DIMENSION_VALUE;
+    private boolean _containerInPageContext = false;
+    private int _columns = DIMENSION_DEFAULT_VALUE;
+    private int _rows = DIMENSION_DEFAULT_VALUE;
     private int _currentIndex = -1;
     private int _currentRow = -1;
     private int _currentColumn = -1;
-    private int _rows = DEFAULT_DIMENSION_VALUE;
+
     private ArrayList _dataList = null;
     private Object _currentItem = null;
     private String _dataSource = null;
-
     private String _altCellClass = null;
     private String _cellClass = null;
-
+    private ConstantRendering _htmlConstantRendering = null;
     private TagRenderingBase _tableRenderer = null;
     private TagRenderingBase _trRenderer = null;
     private TagRenderingBase _tdRenderer = null;
-
     private TableTag.State _tableState = null;
     private TdTag.State _tdState = null;
     private TrTag.State _trState = null;
-
     private InternalStringBuilder _sb = null;
     private AbstractRenderAppender _appender = null;
 
@@ -195,19 +191,6 @@
     }
 
     /**
-     * Add content to the content that is being buffered by this tag.  All 
content
-     * written by the body of this tag is added to this buffer.  The buffer is 
rendered
-     * at the end of the tag's lifecycle if no fatal errors have occurred 
during this
-     * tag's lifecycle.
-     *
-     * @param content content that this tag should render.
-     */
-    public void addContent(String content) {
-        assert _appender != null : "Found null appender buffer";
-        _appender.append(content);
-    }
-
-    /**
      * Set the HTML style class that is rendered on the HTML table that
      * is opened by this tag.  For example, if the row class is "tableClass",
      * each opening table tag is:
@@ -254,9 +237,8 @@
     public void setRowClass(String rowClass) {
         if("".equals(rowClass))
             return;
-
-        _tdState = new TdTag.State();
-        _tdState.styleClass = rowClass;
+        _trState = new TrTag.State();
+        _trState.styleClass = rowClass;
     }
 
     /**
@@ -400,7 +382,7 @@
      * the Controller file ( = JPF file).  The following 
&lt;netui-data:repeater>
      * tag draws its data from myIterativeData.
      *
-     * <p>&nbsp;&nbsp;&nbsp;&nbsp;<code>&lt;netui-data:repeater 
dataSource="{pageFlow.myIterativeData}"></code>
+     * <p>&nbsp;&nbsp;&nbsp;&nbsp;<code>&lt;netui-data:cellRepeater 
dataSource="{pageFlow.myIterativeData}"></code>
      * @jsptagref.databindable Read / Write
      * @jsptagref.attributesyntaxvalue <i>expression_datasource</i>
      * @netui:attribute required="true"
@@ -435,6 +417,7 @@
         _tableRenderer = 
TagRenderingBase.Factory.getRendering(TagRenderingBase.TABLE_TAG, request);
         _trRenderer = 
TagRenderingBase.Factory.getRendering(TagRenderingBase.TR_TAG, request);
         _tdRenderer = 
TagRenderingBase.Factory.getRendering(TagRenderingBase.TD_TAG, request);
+        _htmlConstantRendering = 
TagRenderingBase.Factory.getConstantRendering(request);
 
         _sb = new InternalStringBuilder(1024);
         _appender = new StringBuilderRenderAppender(_sb);
@@ -459,7 +442,7 @@
             }
         }
 
-        if(_rows == DEFAULT_DIMENSION_VALUE || _columns == 
DEFAULT_DIMENSION_VALUE) {
+        if(_rows == DIMENSION_DEFAULT_VALUE || _columns == 
DIMENSION_DEFAULT_VALUE) {
             /* try to guess the dimensions of the table */
             if(_dataList != null && _dataList.size() > 0) {
                 guessDimensions(_dataList);
@@ -467,16 +450,23 @@
                 if(hasErrors())
                     return SKIP_BODY;
             }
-            // can't guess the dimensions
+            /* the size of the data set isn't guessable */
             else {
-                // warn; this isn't an error -- there just isn't any data
                 _valid = false;
                 return SKIP_BODY;
             }
         }
 
-        // check to make sure the rows / columns are actually valid before 
starting to render
-        validateAttributes(_rows, _columns);
+        /* check to make sure the rows / columns are actually valid before 
starting to render */
+        if(_rows <= 0) {
+            String msg = Bundle.getString("Tags_CellRepeater_invalidRowValue", 
new Object[]{getTagName(), new Integer(_rows)});
+            registerTagError(msg, null);
+        }
+
+        if(_columns <= 0) {
+            String msg = 
Bundle.getString("Tags_CellRepeater_invalidColumnValue", new 
Object[]{getTagName(), new Integer(_columns)});
+            registerTagError(msg, null);
+        }
 
         if(hasErrors())
             return SKIP_BODY;
@@ -487,11 +477,12 @@
         _currentColumn = 0;
 
         DataAccessProviderStack.addDataAccessProvider(this, pageContext);
+        _containerInPageContext = true;
 
-        boolean item = ensureItem(0, _dataList);
-        if(item) {
+        boolean haveItem = ensureItem(0, _dataList);
+        if(haveItem) {
             openRowTag(_appender, _trState);
-            openCellTag(_appender, _currentColumn + (_currentRow % 2 == 0 ? 0 
: 1));
+            openCellTag(_appender, _currentColumn);
             return EVAL_BODY_BUFFERED;
         }
         else {
@@ -500,15 +491,14 @@
                 openRowTag(_appender, _trState);
                 for(int j = 0; j < _columns; j++) {
                     openCellTag(_appender, computeStyleIndex(i, j));
-                    _appender.append("&nbsp;");
-                    _tdRenderer.doEndTag(_appender);
+                    _htmlConstantRendering.NBSP(_appender);
+                    closeCellTag(_appender);
                 }
-                _trRenderer.doEndTag(_appender);
+                closeRowTag(_appender);
                 _appender.append("\n");
             }
             _currentRow = _rows;
             _currentColumn = _columns;
-
             return SKIP_BODY;
         }
     }
@@ -524,50 +514,54 @@
      */
     public int doAfterBody() {
         if(bodyContent != null) {
-            addContent(bodyContent.getString());
+            _appender.append(bodyContent.getString());
             bodyContent.clearBody();
         }
 
+        /*
+           this loop exists so that the table is filled out correctly up to 
the specified
+           or guessed table dimensions.  this is a little bit of a kludge; 
this logic should be done
+           in doEndTag()
+         */
         boolean haveNext = false;
         while(!haveNext) {
             _currentColumn++;
 
-            // close the last cell
-            _tdRenderer.doEndTag(_appender);
+            /* close the previous cell whose content was rendered the last 
time the tag body was executed */
+            closeCellTag(_appender);
 
-            // new row; close last row
+            /* open a new table row */
             if(_currentColumn == _columns) {
                 _currentRow++;
                 _currentColumn = 0;
-                _trRenderer.doEndTag(_appender);
+                closeRowTag(_appender);
                 _appender.append("\n");
             }
 
-            // end
-            if(_currentRow == _rows && _currentColumn == 0)
+            /* reached the end of the table as the current row is now equal to 
the total number of rows */
+            if(_currentRow == _rows)
                 return SKIP_BODY;
 
             if(_currentColumn == 0)
-                openRowTag(_appender, _trState != null ? _trState : TR_STATE);
+                openRowTag(_appender, _trState != null ? _trState : STATE_TR);
 
+            int itemIndex = -1;
             if(_verticalRepeat)
-                haveNext = ensureItem(_currentColumn * _rows + _currentRow, 
_dataList);
-            else
-                haveNext = ensureItem(_currentRow * _columns + _currentColumn, 
_dataList);
-
-            if(!haveNext) {
-                LOGGER.debug("missing next at location (" + _currentRow + ", " 
+ _currentColumn + ")");
-
-                // render empty cell
-                openCellTag(_appender, computeStyleIndex(_currentRow,  
_currentColumn)) ;
-                _appender.append("&nbsp;");
-            }
-            else {
-                openCellTag(_appender, computeStyleIndex(_currentRow,  
_currentColumn)) ;
-                return EVAL_BODY_AGAIN;
-            }
+                itemIndex = _currentColumn * _rows + _currentRow;
+            else itemIndex = _currentRow * _columns + _currentColumn;
+
+            haveNext = ensureItem(itemIndex, _dataList);
+
+            openCellTag(_appender, computeStyleIndex(_currentRow,  
_currentColumn)) ;
+
+            /* render empty cell and continue filling the table */
+            if(!haveNext)
+                _htmlConstantRendering.NBSP(_appender);
+            /* open a new table cell and render the body once again.  note, 
this exits the while loop above */
+            else return EVAL_BODY_AGAIN;
         }
 
+        /* default is to skip the tag body */
         return SKIP_BODY;
     }
 
@@ -580,15 +574,15 @@
      */
     public int doEndTag()
             throws JspException {
-        if(hasErrors()) {
+        if(hasErrors())
             reportErrors();
-        }
         else if(_valid) {
-            _tableRenderer.doEndTag(_appender);
+            closeTableTag(_appender);
             write(_sb.toString());
         }
 
         DataAccessProviderStack.removeDataAccessProvider(pageContext);
+        _containerInPageContext = false;
 
         return EVAL_PAGE;
     }
@@ -667,8 +661,8 @@
         if(bodyContent != null)
             bodyContent.clearBody();
 
-        _rows = DEFAULT_DIMENSION_VALUE;
-        _columns = DEFAULT_DIMENSION_VALUE;
+        _rows = DIMENSION_DEFAULT_VALUE;
+        _columns = DIMENSION_DEFAULT_VALUE;
         _currentRow = -1;
         _currentColumn = -1;
         _currentIndex = -1;
@@ -691,80 +685,92 @@
 
         _sb = null;
         _appender = null;
-    }
 
-    private void reportBasicError(String message)
-            throws JspException {
-        registerTagError(message, null);
+        if(_containerInPageContext) {
+            DataAccessProviderStack.removeDataAccessProvider(pageContext);
+            _containerInPageContext = false;
+        }
     }
 
-    private void guessDimensions(List data)
-            throws JspException {
+    private final void guessDimensions(ArrayList data)
+        throws JspException {
+
         if(_rows == 0 || _columns == 0)
-            
reportBasicError(Bundle.getString("Tags_CellRepeater_missingRowsOrColumns"));
+            
registerTagError(Bundle.getString("Tags_CellRepeater_missingRowsOrColumns"), 
null);
 
         if(data == null)
             return;
 
         int dataSize = data.size();
-        if(_rows == DEFAULT_DIMENSION_VALUE && _columns == 
DEFAULT_DIMENSION_VALUE) {
-            
reportBasicError(Bundle.getString("Tags_CellRepeater_invalidRowOrColumn"));
+        if(_rows == DIMENSION_DEFAULT_VALUE && _columns == 
DIMENSION_DEFAULT_VALUE) {
+            
registerTagError(Bundle.getString("Tags_CellRepeater_invalidRowOrColumn"), 
null);
         }
-        else if(_rows == DEFAULT_DIMENSION_VALUE) {
+        else if(_rows == DIMENSION_DEFAULT_VALUE) {
             int remainder = dataSize % _columns;
             _rows = (dataSize / _columns) + (remainder > 0 ? 1 : 0);
             LOGGER.debug("guessed row size: " + _rows);
         }
-        else if(_columns == DEFAULT_DIMENSION_VALUE) {
+        else if(_columns == DIMENSION_DEFAULT_VALUE) {
             int remainder = dataSize % _rows;
             _columns = (dataSize / _rows) + (remainder > 0 ? 1 : 0);
             LOGGER.debug("guessed column size: " + _columns);
         }
     }
 
-    private void validateAttributes(int rows, int columns)
-        throws JspException {
-        if(rows <= 0) {
-            String msg = Bundle.getString("Tags_CellRepeater_invalidRowValue", 
new Object[]{getTagName(), new Integer(rows)});
-            registerTagError(msg, null);
-        }
-
-        if(columns <= 0) {
-            String msg = 
Bundle.getString("Tags_CellRepeater_invalidColumnValue", new 
Object[]{getTagName(), new Integer(columns)});
-            registerTagError(msg, null);
-        }
-    }
-
     private final void openTableTag(AbstractRenderAppender appender, 
TableTag.State tableState) {
         if(tableState == null)
-            tableState = TABLE_STATE;
+            tableState = STATE_TABLE;
         _tableRenderer.doStartTag(appender, tableState);
     }
 
+    private final void closeTableTag(AbstractRenderAppender appender) {
+        assert appender != null;
+        assert _tableRenderer != null;
+        _tableRenderer.doEndTag(appender);
+    }
+
     private final void openRowTag(AbstractRenderAppender appender, TrTag.State 
trState) {
         if(trState == null)
-            trState = TR_STATE;
+            trState = STATE_TR;
         _trRenderer.doStartTag(appender, trState);
     }
 
+    private final void closeRowTag(AbstractRenderAppender appender) {
+        assert _trRenderer != null;
+        assert appender != null;
+        _trRenderer.doEndTag(appender);
+    }
+
     private final void openCellTag(AbstractRenderAppender appender, int index) 
{
-        TdTag.State tdState = TD_STATE;
-        /* todo: need to clear the TdTag.State here rather than recreate */
+        assert appender != null;
+        assert index >= 0;
+        assert _tdRenderer != null;
+
+        TdTag.State tdState = STATE_TD;
         if(_cellClass != null) {
-            tdState = new TdTag.State();
+            if(_tdState != null)
+                _tdState.clear();
+            else _tdState = new TdTag.State();
             if(index % 2 == 0)
-                tdState.styleClass = _cellClass;
-            else tdState.styleClass = (_altCellClass != null ? _altCellClass : 
_cellClass);
+                _tdState.styleClass = _cellClass;
+            else _tdState.styleClass = (_altCellClass != null ? _altCellClass 
: _cellClass);
+            tdState = _tdState;
         }
 
         _tdRenderer.doStartTag(appender, tdState);
     }
 
+    private final void closeCellTag(AbstractRenderAppender appender) {
+        assert _tdRenderer != null;
+        assert appender != null;
+        _tdRenderer.doEndTag(appender);
+    }
+
     private final int computeStyleIndex(int r, int c) {
         return c + (r % 2);
     }
 
-    private boolean ensureItem(int index, List data) {
+    private boolean ensureItem(int index, ArrayList data) {
         LOGGER.debug("item: " + 0 + " data: " + (data == null ? "null data" :
                      (index < data.size() ? "" + index : "index out of bounds 
for size " + data.size())));
 
@@ -799,8 +805,7 @@
         if (ds == null)
             return null;
 
-        // have a valid expression
         Object o = expr.evaluateExpression(dataSource, "dataSource", 
pageContext);
         return o;
     }
-}
+}
\ No newline at end of file


Reply via email to