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> <td>&nbsp;</td></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
<netui-data:repeater>
* tag draws its data from myIterativeData.
*
- * <p> <code><netui-data:repeater
dataSource="{pageFlow.myIterativeData}"></code>
+ * <p> <code><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(" ");
- _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(" ");
- }
- 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