📄 webtable.java
字号:
package com.meterware.httpunit;/********************************************************************************************************************* $Id: WebTable.java,v 1.31 2006/03/09 01:52:28 russgold Exp $** Copyright (c) 2000-2005, Russell Gold** Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated* documentation files (the "Software"), to deal in the Software without restriction, including without limitation* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and* to permit persons to whom the Software is furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included in all copies or substantial portions* of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER* DEALINGS IN THE SOFTWARE.********************************************************************************************************************/import com.meterware.httpunit.scripting.ScriptableDelegate;import org.w3c.dom.Element;import org.w3c.dom.Node;import java.net.URL;import java.util.ArrayList;import java.util.Enumeration;import java.util.Hashtable;/** * This class represents a table in an HTML page. * * @author <a href="mailto:russgold@httpunit.org">Russell Gold</a> * @author <a href="mailto:bx@bigfoot.com">Benoit Xhenseval</a> **/public class WebTable extends HTMLElementBase { /** Predicate to match the complete text of a table's first non-blank cell. **/ public final static HTMLElementPredicate MATCH_FIRST_NONBLANK_CELL; /** Predicate to match a prefix of a table's first non-blank cell. **/ public final static HTMLElementPredicate MATCH_FIRST_NONBLANK_CELL_PREFIX; /** Predicate to match a table's summary attribute. **/ public final static HTMLElementPredicate MATCH_SUMMARY; /** Predicate to match a table's ID. **/ public final static HTMLElementPredicate MATCH_ID; /** * Returns the number of rows in the table. **/ public int getRowCount() { return getCells().length; } private TableCell[][] getCells() { if (_cells == null) readTable(); return _cells; } /** * Returns the number of columns in the table. **/ public int getColumnCount() { if (getCells().length == 0) return 0; return getCells()[0].length; } /** * Returns the contents of the specified table cell as text. * The row and column numbers are zero-based. * @throws IndexOutOfBoundsException if the specified cell numbers are not valid **/ public String getCellAsText( int row, int column ) { TableCell cell = getTableCell( row, column ); return (cell == null) ? "" : cell.getText(); } /** * Returns the contents of the specified table cell as text. * The row and column numbers are zero-based. * @throws IndexOutOfBoundsException if the specified cell numbers are not valid **/ public TableCell getTableCell( int row, int column ) { return getCells()[ row ][ column ]; } /** * Returns the contents of the specified table cell with a given ID * @return TableCell with given ID or null if ID is not found. **/ public TableCell getTableCellWithID( String id ) { for (int i = 0; i < getRowCount(); i++) { for (int j = 0; j < getColumnCount(); j++) { final TableCell tableCell = getCells()[i][j]; if (tableCell!=null && tableCell.getID().equals( id )) return tableCell; } } return null; } /** * Removes all rows and all columns from this table which have no visible text in them. **/ public void purgeEmptyCells() { int numRowsWithText = 0; int numColumnsWithText = 0; boolean rowHasText[] = new boolean[ getRowCount() ]; boolean columnHasText[] = new boolean[ getColumnCount() ]; Hashtable spanningCells = new Hashtable(); // look for rows and columns with any text in a non-spanning cell for (int i = 0; i < rowHasText.length; i++) { for (int j = 0; j < columnHasText.length; j++) { if (getCellAsText(i,j).trim().length() == 0) continue; if (getTableCell(i,j).getColSpan() == 1 && getTableCell(i,j).getRowSpan() == 1) { if (!rowHasText[i]) numRowsWithText++; if (!columnHasText[j]) numColumnsWithText++; rowHasText[i] = columnHasText[j] = true; } else if (!spanningCells.containsKey( getTableCell(i,j) )) { spanningCells.put( getTableCell(i,j), new int[] { i, j } ); } } } // look for requirements to keep spanning cells: special processing is needed if either: // none of its rows already have text, or none of its columns already have text. for (Enumeration e = spanningCells.keys(); e.hasMoreElements();) { TableCell cell = (TableCell) e.nextElement(); int coords[] = (int[]) spanningCells.get( cell ); boolean neededInRow = true; boolean neededInCol = true; for (int i = coords[0]; neededInRow && (i < rowHasText.length) && (i < coords[0] + cell.getRowSpan()); i++) { neededInRow = !rowHasText[i]; } for (int j = coords[1]; neededInCol && (j < columnHasText.length) && (j < coords[1] + cell.getColSpan()); j++) { neededInCol = !columnHasText[j]; } if (neededInRow) { rowHasText[ coords[0] ] = true; numRowsWithText++; } if (neededInCol) { columnHasText[ coords[1] ] = true; numColumnsWithText++; } } TableCell[][] remainingCells = new TableCell[ numRowsWithText ][ numColumnsWithText ]; int targetRow = 0; for (int i = 0; i < rowHasText.length; i++) { if (!rowHasText[i]) continue; int targetColumn = 0; for (int j = 0; j < columnHasText.length; j++) { if (!columnHasText[j]) continue; remainingCells[ targetRow ][ targetColumn++ ] = _cells[i][j]; } targetRow++; } _cells = remainingCells; } /** * Returns a rendering of this table with all cells converted to text. **/ public String[][] asText() { String[][] result = new String[ getRowCount() ][ getColumnCount() ]; for (int i = 0; i < result.length; i++) { for (int j= 0; j < result[0].length; j++) { result[i][j] = getCellAsText( i, j ); } } return result; } /** * Returns the summary attribute associated with this table. **/ public String getSummary() { return NodeUtils.getNodeAttribute( _dom, "summary" ); } public String toString() { String eol = System.getProperty( "line.separator" ); StringBuffer sb = new StringBuffer( HttpUnitUtils.DEFAULT_TEXT_BUFFER_SIZE).append("WebTable:" ).append( eol ); for (int i = 0; i < getCells().length; i++) { sb.append( "[" ).append( i ).append( "]: " ); for (int j = 0; j < getCells()[i].length; j++) { sb.append( " [" ).append( j ).append( "]=" ); if (getCells()[i][j] == null) { sb.append( "null" ); } else { sb.append( getCells()[i][j].getText() ); } } sb.append( eol ); } return sb.toString(); } protected ScriptableDelegate newScriptable() { return new HTMLElementScriptable( this ); } protected ScriptableDelegate getParentDelegate() { return _response.getScriptableObject().getDocument(); }//----------------------------------- private members ----------------------------------- private Element _dom; private URL _url; private FrameSelector _frameName; private String _baseTarget; private String _characterSet; private WebResponse _response; private TableCell[][] _cells; WebTable( WebResponse response, FrameSelector frame, Node domTreeRoot, URL sourceURL, String baseTarget, String characterSet ) { super( domTreeRoot ); _response = response; _frameName = frame; _dom = (Element) domTreeRoot; _url = sourceURL; _baseTarget = baseTarget; _characterSet = characterSet; } private void readTable() { TableRow[] rows = getRows(); int[] columnsRequired = new int[ rows.length ]; for (int i = 0; i < rows.length; i++) { TableCell[] cells = rows[i].getCells(); for (int j = 0; j < cells.length; j++) { int spannedRows = Math.min( columnsRequired.length-i, cells[j].getRowSpan() ); for (int k = 0; k < spannedRows; k++) { columnsRequired[ i+k ]+= cells[j].getColSpan(); } } } int numColumns = 0; for (int i = 0; i < columnsRequired.length; i++) { numColumns = Math.max( numColumns, columnsRequired[i] ); } _cells = new TableCell[ columnsRequired.length ][ numColumns ]; for (int i = 0; i < rows.length; i++) { TableCell[] cells = rows[i].getCells(); for (int j = 0; j < cells.length; j++) { int spannedRows = Math.min( columnsRequired.length-i, cells[j].getRowSpan() ); for (int k = 0; k < spannedRows; k++) { for (int l = 0; l < cells[j].getColSpan(); l++) { placeCell( i+k, j+l, cells[j] ); } } } } } private void placeCell( int row, int column, TableCell cell ) { while (_cells[ row ][ column ] != null) column++; _cells[ row ][ column ] = cell; } private ArrayList _rows = new ArrayList(); void addRow( TableRow tableRow ) { _cells = null; _rows.add( tableRow ); } TableRow newTableRow( Element element ) { return new TableRow( this, element ); } /** * Returns an array of rows for this table. */ public TableRow[] getRows() { return (TableRow[]) _rows.toArray( new TableRow[ _rows.size() ] ); } TableCell newTableCell( Element element ) { return new TableCell( _response, _frameName, element, _url, _baseTarget, _characterSet ); } static { MATCH_FIRST_NONBLANK_CELL = new HTMLElementPredicate() { // XXX find a way to do this w/o purging the table cells public boolean matchesCriteria( Object htmlElement, Object criteria ) { WebTable table = ((WebTable) htmlElement); table.purgeEmptyCells(); return table.getRowCount() > 0 && HttpUnitUtils.matches( table.getCellAsText(0,0).trim(), (String) criteria ); }; }; MATCH_FIRST_NONBLANK_CELL_PREFIX = new HTMLElementPredicate() { // XXX find a way to do this w/o purging the table cells public boolean matchesCriteria( Object htmlElement, Object criteria ) { WebTable table = ((WebTable) htmlElement); table.purgeEmptyCells(); return table.getRowCount() > 0 && HttpUnitUtils.hasPrefix( table.getCellAsText(0,0).toUpperCase().trim(), (String) criteria ); }; }; MATCH_ID = new HTMLElementPredicate() { public boolean matchesCriteria( Object htmlElement, Object criteria ) { return HttpUnitUtils.matches( ((WebTable) htmlElement).getID(), (String) criteria ); }; }; MATCH_SUMMARY = new HTMLElementPredicate() { public boolean matchesCriteria( Object htmlElement, Object criteria ) { return HttpUnitUtils.matches( ((WebTable) htmlElement).getSummary(), (String) criteria ); }; }; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -