You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2012/03/30 03:12:31 UTC
svn commit: r1307198 - in /myfaces:
core/branches/1.2.x/impl/src/test/java/org/apache/myfaces/renderkit/html/HtmlTableRendererTest.java
shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java
Author: lu4242
Date: Fri Mar 30 01:12:31 2012
New Revision: 1307198
URL: http://svn.apache.org/viewvc?rev=1307198&view=rev
Log:
MYFACES-3518 and MYFACES-1528 Regression: <h:DataTable> empty with CachedRowSet
Modified:
myfaces/core/branches/1.2.x/impl/src/test/java/org/apache/myfaces/renderkit/html/HtmlTableRendererTest.java
myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java
Modified: myfaces/core/branches/1.2.x/impl/src/test/java/org/apache/myfaces/renderkit/html/HtmlTableRendererTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/test/java/org/apache/myfaces/renderkit/html/HtmlTableRendererTest.java?rev=1307198&r1=1307197&r2=1307198&view=diff
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/test/java/org/apache/myfaces/renderkit/html/HtmlTableRendererTest.java (original)
+++ myfaces/core/branches/1.2.x/impl/src/test/java/org/apache/myfaces/renderkit/html/HtmlTableRendererTest.java Fri Mar 30 01:12:31 2012
@@ -19,8 +19,14 @@
package org.apache.myfaces.renderkit.html;
import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import javax.faces.component.UIColumn;
+import javax.faces.component.behavior.AjaxBehavior;
import javax.faces.component.html.HtmlDataTable;
+import javax.faces.component.html.HtmlOutputText;
+import javax.faces.model.ListDataModel;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -64,6 +70,11 @@ public class HtmlTableRendererTest exten
dataTable.getRendererType(),
new HtmlTableRenderer());
+ HtmlOutputText text = new HtmlOutputText();
+ facesContext.getRenderKit().addRenderer(
+ text.getFamily(),
+ text.getRendererType(),
+ new HtmlTextRenderer());
}
public void tearDown() throws Exception
@@ -94,4 +105,148 @@ public class HtmlTableRendererTest exten
fail(HtmlCheckAttributesUtil.constructErrorMessage(attrs, writer.getWriter().toString()));
}
}
+
+ /**
+ * Components that render client behaviors should always render "id" and "name" attribute
+ */
+ public void testClientBehaviorHolderRendersIdAndName()
+ {
+ dataTable.addClientBehavior("keypress", new AjaxBehavior());
+ try
+ {
+ dataTable.encodeAll(facesContext);
+ String output = ((StringWriter) writer.getWriter()).getBuffer().toString();
+ assertTrue(output.matches("(?s).+id=\".+\".+"));
+ assertTrue(output.matches("(?s).+name=\".+\".+"));
+ }
+ catch (Exception e)
+ {
+ fail(e.getMessage());
+ }
+
+ }
+
+ /**
+ * Check table renderer behavior when DataModel returns -1 from getRowCount(). It should
+ * render the same as if that value is provided. Note t:dataTable newspaper mode requires
+ * row count to calculate newspaperRows and newspaperColumns.
+ */
+ public void testNoRowCountRender()
+ {
+ List<Person> list = new ArrayList<Person>();
+ list.add(new Person("John" , "Smith"));
+ list.add(new Person("Pepito", "Perez"));
+ list.add(new Person("Kurt", "Kobain"));
+
+ dataTable.setId("data");
+ dataTable.setRowClasses("class1, class2");
+ dataTable.setVar("person");
+
+ UIColumn column1 = new UIColumn();
+ HtmlOutputText text = new HtmlOutputText();
+ text.setValueExpression("value",
+ facesContext.getApplication().getExpressionFactory().createValueExpression(
+ facesContext.getELContext(), "#{person.firstName}", String.class));
+ column1.getChildren().add(text);
+
+ dataTable.getChildren().add(column1);
+ UIColumn column2 = new UIColumn();
+ HtmlOutputText text2 = new HtmlOutputText();
+ text2.setValueExpression("value",
+ facesContext.getApplication().getExpressionFactory().createValueExpression(
+ facesContext.getELContext(), "#{person.lastName}", String.class));
+ column2.getChildren().add(text2);
+ dataTable.getChildren().add(column2);
+
+ dataTable.setValue(new UnknownRowCountDemoDataModel<Person>(list));
+
+ String output1 = null;
+ try
+ {
+ dataTable.encodeAll(facesContext);
+ output1 = ((StringWriter) writer.getWriter()).getBuffer().toString();
+ }
+ catch (Exception e)
+ {
+ fail(e.getMessage());
+ }
+
+ dataTable.setValue(new ListDataModel<Person>(list));
+ ((StringWriter) writer.getWriter()).getBuffer().setLength(0);
+
+ String output2 = null;
+ try
+ {
+ dataTable.encodeAll(facesContext);
+ output2 = ((StringWriter) writer.getWriter()).getBuffer().toString();
+ }
+ catch (Exception e)
+ {
+ fail(e.getMessage());
+ }
+
+ assertTrue(output2.contains("John"));
+ assertTrue(output2.contains("Smith"));
+ assertTrue(output2.contains("class1"));
+ assertTrue(output2.contains("class2"));
+
+ assertTrue(output1.contains("John"));
+ assertTrue(output1.contains("Smith"));
+ assertTrue(output1.contains("class1"));
+ assertTrue(output1.contains("class2"));
+
+ assertEquals(output2, output1);
+ }
+
+ public class Person
+ {
+ private String firstName;
+
+ private String lastName;
+
+ public Person(String firstName, String lastName)
+ {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public String getFirstName()
+ {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName)
+ {
+ this.firstName = firstName;
+ }
+
+ public String getLastName()
+ {
+ return lastName;
+ }
+
+ public void setLastName(String lastName)
+ {
+ this.lastName = lastName;
+ }
+ }
+
+ public class UnknownRowCountDemoDataModel<E> extends ListDataModel<E>
+ {
+ public UnknownRowCountDemoDataModel()
+ {
+ super();
+ }
+
+ public UnknownRowCountDemoDataModel(List<E> list)
+ {
+ super(list);
+ }
+
+ @Override
+ public int getRowCount()
+ {
+ return -1;
+ }
+ }
}
Modified: myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java?rev=1307198&r1=1307197&r2=1307198&view=diff
==============================================================================
--- myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java (original)
+++ myfaces/shared/trunk_3.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java Fri Mar 30 01:12:31 2012
@@ -218,6 +218,7 @@ public class HtmlTableRendererBase exten
}
}
+
/**
* Renders everything inside the TBODY tag by iterating over the row objects
* between offsets first and first+rows and applying the UIColumn components
@@ -233,7 +234,16 @@ public class HtmlTableRendererBase exten
int rowCount = uiData.getRowCount();
- if (rowCount == 0) {
+ int newspaperColumns = getNewspaperColumns(component);
+
+ if (rowCount == -1 && newspaperColumns == 1)
+ {
+ encodeInnerHtmlUnknownRowCount(facesContext, component);
+ return;
+ }
+
+ if (rowCount == 0)
+ {
//nothing to render, to get valid xhtml we render an empty dummy row
writer.startElement(HTML.TR_ELEM, uiData);
writer.startElement(HTML.TD_ELEM, uiData);
@@ -263,11 +273,15 @@ public class HtmlTableRendererBase exten
}
}
- int newspaperColumns = getNewspaperColumns(component);
int newspaperRows;
if((last - first) % newspaperColumns == 0)
+ {
newspaperRows = (last - first) / newspaperColumns;
- else newspaperRows = ((last - first) / newspaperColumns) + 1;
+ }
+ else
+ {
+ newspaperRows = ((last - first) / newspaperColumns) + 1;
+ }
boolean newspaperHorizontalOrientation = isNewspaperHorizontalOrientation(component);
// walk through the newspaper rows
@@ -275,26 +289,36 @@ public class HtmlTableRendererBase exten
{
boolean rowStartRendered = false;
// walk through the newspaper columns
- for(int nc = 0; nc < newspaperColumns; nc++) {
+ for(int nc = 0; nc < newspaperColumns; nc++)
+ {
// the current row in the 'real' table
int currentRow;
if (newspaperHorizontalOrientation)
+ {
currentRow = nr * newspaperColumns + nc + first;
+ }
else
+ {
currentRow = nc * newspaperRows + nr + first;
+ }
// if this row is not to be rendered
- if(currentRow >= last) continue;
+ if(currentRow >= last)
+ {
+ continue;
+ }
// bail if any row does not exist
uiData.setRowIndex(currentRow);
- if(!uiData.isRowAvailable()) {
+ if(!uiData.isRowAvailable())
+ {
log.error("Row is not available. Rowindex = " + currentRow);
break;
}
- if (nc == 0) {
+ if (nc == 0)
+ {
// first column in table, start new row
beforeRow(facesContext, uiData);
@@ -303,28 +327,40 @@ public class HtmlTableRendererBase exten
rowStartRendered = true;
}
- List children = getChildren(component);
+ List children = null;
for (int j = 0, size = getChildCount(component); j < size; j++)
{
+ if (children == null)
+ {
+ children = getChildren(component);
+ }
UIComponent child = (UIComponent) children.get(j);
if (child.isRendered())
{
boolean columnRendering = child instanceof UIColumn;
if (columnRendering)
+ {
beforeColumn(facesContext, uiData, j);
+ }
- encodeColumnChild(facesContext, writer, uiData, child, styles, nc * uiData.getChildCount() + j);
+ encodeColumnChild(facesContext, writer, uiData, child,
+ styles, nc * uiData.getChildCount() + j);
if (columnRendering)
+ {
afterColumn(facesContext, uiData, j);
+ }
}
}
if (hasNewspaperTableSpacer(uiData))
{
// draw the spacer facet
- if(nc < newspaperColumns - 1) renderSpacerCell(facesContext, writer, uiData);
+ if(nc < newspaperColumns - 1)
+ {
+ renderSpacerCell(facesContext, writer, uiData);
+ }
}
}
if (rowStartRendered)
@@ -335,6 +371,83 @@ public class HtmlTableRendererBase exten
}
}
+ private void encodeInnerHtmlUnknownRowCount(FacesContext facesContext, UIComponent component)throws IOException
+ {
+ UIData uiData = (UIData) component;
+ ResponseWriter writer = facesContext.getResponseWriter();
+
+ Styles styles = getStyles(uiData);
+
+ int first = uiData.getFirst();
+ int rows = uiData.getRows();
+ int currentRow = first;
+ boolean isRowRendered = false;
+
+ while(true)
+ {
+ uiData.setRowIndex(currentRow);
+ if (!uiData.isRowAvailable())
+ {
+ break;
+ }
+
+ isRowRendered = true;
+
+ // first column in table, start new row
+ beforeRow(facesContext, uiData);
+
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ renderRowStart(facesContext, writer, uiData, styles, currentRow);
+
+ List<UIComponent> children = null;
+ for (int j = 0, size = getChildCount(component); j < size; j++)
+ {
+ if (children == null)
+ {
+ children = getChildren(component);
+ }
+ UIComponent child = (UIComponent) children.get(j);
+ if (child.isRendered())
+ {
+ boolean columnRendering = child instanceof UIColumn;
+
+ if (columnRendering)
+ {
+ beforeColumn(facesContext, uiData, j);
+ }
+
+ encodeColumnChild(facesContext, writer, uiData, child,
+ styles, j);
+
+ if (columnRendering)
+ {
+ afterColumn(facesContext, uiData, j);
+ }
+ }
+ }
+
+ renderRowEnd(facesContext, writer, uiData);
+ afterRow(facesContext, uiData);
+
+ currentRow++;
+
+ if (rows > 0 && currentRow-first > rows )
+ {
+ break;
+ }
+ }
+
+ if (!isRowRendered)
+ {
+ //nothing to render, to get valid xhtml we render an empty dummy row
+ writer.startElement(HTML.TR_ELEM, uiData);
+ writer.startElement(HTML.TD_ELEM, uiData);
+ writer.endElement(HTML.TD_ELEM);
+ writer.endElement(HTML.TR_ELEM);
+ return;
+ }
+ }
+
protected void encodeColumnChild(FacesContext facesContext, ResponseWriter writer,
UIData uiData, UIComponent component, Styles styles, int columnStyleIndex) throws IOException
{