Return-Path: X-Original-To: apmail-myfaces-commits-archive@www.apache.org Delivered-To: apmail-myfaces-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0AE40907A for ; Fri, 30 Mar 2012 01:12:54 +0000 (UTC) Received: (qmail 82701 invoked by uid 500); 30 Mar 2012 01:12:53 -0000 Delivered-To: apmail-myfaces-commits-archive@myfaces.apache.org Received: (qmail 82645 invoked by uid 500); 30 Mar 2012 01:12:53 -0000 Mailing-List: contact commits-help@myfaces.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "MyFaces Development" Delivered-To: mailing list commits@myfaces.apache.org Received: (qmail 82638 invoked by uid 99); 30 Mar 2012 01:12:53 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 01:12:53 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 01:12:51 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id DE53C238897A for ; Fri, 30 Mar 2012 01:12:31 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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 Date: Fri, 30 Mar 2012 01:12:31 -0000 To: commits@myfaces.apache.org From: lu4242@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120330011231.DE53C238897A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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: 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 list = new ArrayList(); + 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(list)); + + String output1 = null; + try + { + dataTable.encodeAll(facesContext); + output1 = ((StringWriter) writer.getWriter()).getBuffer().toString(); + } + catch (Exception e) + { + fail(e.getMessage()); + } + + dataTable.setValue(new ListDataModel(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 extends ListDataModel + { + public UnknownRowCountDemoDataModel() + { + super(); + } + + public UnknownRowCountDemoDataModel(List 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 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 {