[Httpunit-commit] CVS: httpunit/src/com/meterware/httpunit HTMLSegment.java,1.7,1.8 NodeUtils.java,1
Brought to you by:
russgold
|
From: Russell G. <rus...@us...> - 2002-12-26 15:34:00
|
Update of /cvsroot/httpunit/httpunit/src/com/meterware/httpunit
In directory sc8-pr-cvs1:/tmp/cvs-serv21758/src/com/meterware/httpunit
Modified Files:
HTMLSegment.java NodeUtils.java ParsedHTML.java TableCell.java
WebForm.java WebImage.java WebLink.java WebTable.java
Log Message:
Expanded HTMLElement support to TableRow and TableCell
Index: HTMLSegment.java
===================================================================
RCS file: /cvsroot/httpunit/httpunit/src/com/meterware/httpunit/HTMLSegment.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- HTMLSegment.java 12 Nov 2002 13:41:54 -0000 1.7
+++ HTMLSegment.java 26 Dec 2002 15:33:56 -0000 1.8
@@ -23,9 +23,17 @@
/**
* Represents the parse tree for a segment of HTML.
- * @author Russell Gold
+ *
+ * @author <a href="mailto:rus...@ht...">Russell Gold</a>
**/
public interface HTMLSegment {
+
+
+ /**
+ * Returns the HTMLElement found in this segment with the specified ID.
+ * @exception SAXException thrown if there is an error parsing the segment.
+ */
+ public HTMLElement getElementWithID( String id ) throws SAXException;
/**
Index: NodeUtils.java
===================================================================
RCS file: /cvsroot/httpunit/httpunit/src/com/meterware/httpunit/NodeUtils.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- NodeUtils.java 26 Dec 2002 04:59:35 -0000 1.16
+++ NodeUtils.java 26 Dec 2002 15:33:56 -0000 1.17
@@ -153,6 +153,19 @@
}
+ /**
+ * Returns the most recently pushed context which implements the specified class.
+ * Will return null if no matching context is found.
+ */
+ public Object getClosestContext( Class matchingClass ) {
+ for (int i = _traversalContext.size()-1; i >= 0; i-- ) {
+ Object o = _traversalContext.elementAt( i );
+ if (matchingClass.isInstance(o)) return o;
+ }
+ return null;
+ }
+
+
public void perform( NodeAction action ) {
while (!_pendingNodes.empty()) {
final Object object = _pendingNodes.pop();
Index: ParsedHTML.java
===================================================================
RCS file: /cvsroot/httpunit/httpunit/src/com/meterware/httpunit/ParsedHTML.java,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- ParsedHTML.java 26 Dec 2002 04:59:35 -0000 1.39
+++ ParsedHTML.java 26 Dec 2002 15:33:56 -0000 1.40
@@ -185,83 +185,126 @@
abstract static class HTMLElementFactory {
- abstract HTMLElement toHTMLElement( ParsedHTML parsedHTML, Element element );
- void recordElement( NodeUtils.PreOrderTraversal pot, Element element, HTMLElement htmlElement ) {
+ abstract HTMLElement toHTMLElement( NodeUtils.PreOrderTraversal pot, ParsedHTML parsedHTML, Element element );
+
+ void recordElement( NodeUtils.PreOrderTraversal pot, Element element, ParsedHTML parsedHTML ) {
+ HTMLElement htmlElement = toHTMLElement( pot, parsedHTML, element );
if (htmlElement != null) {
addToMaps( pot, element, htmlElement );
addToLists( pot, htmlElement );
}
}
+
+ protected boolean addToContext() { return false; }
protected void addToLists( NodeUtils.PreOrderTraversal pot, HTMLElement htmlElement ) {
for (Iterator i = pot.getContexts(); i.hasNext();) {
Object o = i.next();
if (o instanceof ParsedHTML) ((ParsedHTML) o).addToList( htmlElement );
}
}
+
protected void addToMaps( NodeUtils.PreOrderTraversal pot, Element element, HTMLElement htmlElement ) {
for (Iterator i = pot.getContexts(); i.hasNext();) {
Object o = i.next();
if (o instanceof ParsedHTML) ((ParsedHTML) o).addToMaps( element, htmlElement );
}
}
+
+ final protected ParsedHTML getParsedHTML( NodeUtils.PreOrderTraversal pot ) {
+ return (ParsedHTML) getClosestContext( pot, ParsedHTML.class );
+ }
+
+ final protected Object getClosestContext( NodeUtils.PreOrderTraversal pot, Class aClass ) {
+ return pot.getClosestContext( aClass );
+ }
}
static class WebFormFactory extends HTMLElementFactory {
- HTMLElement toHTMLElement( ParsedHTML parsedHTML, Element element ) {
+ HTMLElement toHTMLElement( NodeUtils.PreOrderTraversal pot, ParsedHTML parsedHTML, Element element ) {
return parsedHTML.toWebForm( element );
}
}
static class WebLinkFactory extends HTMLElementFactory {
- HTMLElement toHTMLElement( ParsedHTML parsedHTML, Element element ) {
+ HTMLElement toHTMLElement( NodeUtils.PreOrderTraversal pot, ParsedHTML parsedHTML, Element element ) {
return parsedHTML.toLinkAnchor( element );
}
}
static class WebImageFactory extends HTMLElementFactory {
- HTMLElement toHTMLElement( ParsedHTML parsedHTML, Element element ) {
+ HTMLElement toHTMLElement( NodeUtils.PreOrderTraversal pot, ParsedHTML parsedHTML, Element element ) {
return parsedHTML.toWebImage( element );
}
}
static class WebAppletFactory extends HTMLElementFactory {
- HTMLElement toHTMLElement( ParsedHTML parsedHTML, Element element ) {
+ HTMLElement toHTMLElement( NodeUtils.PreOrderTraversal pot, ParsedHTML parsedHTML, Element element ) {
return parsedHTML.toWebApplet( element );
}
}
static class WebTableFactory extends HTMLElementFactory {
- HTMLElement toHTMLElement( ParsedHTML parsedHTML, Element element ) {
+ HTMLElement toHTMLElement( NodeUtils.PreOrderTraversal pot, ParsedHTML parsedHTML, Element element ) {
return parsedHTML.toWebTable( element );
}
+ protected boolean addToContext() { return true; }
+
+ protected void addToLists( NodeUtils.PreOrderTraversal pot, HTMLElement htmlElement ) {
+ getParsedHTML( pot ).addToList( htmlElement );
+ }
+ }
+
+
+ static class TableRowFactory extends HTMLElementFactory {
+ HTMLElement toHTMLElement( NodeUtils.PreOrderTraversal pot, ParsedHTML parsedHTML, Element element ) {
+ WebTable wt = getWebTable( pot );
+ if (wt == null) return null;
+ return wt.newTableRow( element );
+ }
+ private WebTable getWebTable( NodeUtils.PreOrderTraversal pot ) {
+ return (WebTable) getClosestContext( pot, WebTable.class );
+ }
+ protected boolean addToContext() { return true; }
+ protected void addToLists( NodeUtils.PreOrderTraversal pot, HTMLElement htmlElement ) {
+ getWebTable( pot ).addRow( (WebTable.TableRow) htmlElement );
+ }
+ }
-// protected void addToLists( NodeUtils.PreOrderTraversal pot, HTMLElement htmlElement ) {
-// for (Iterator i = pot.getContexts(); i.hasNext();) {
-// Object o = i.next();
-// if (o instanceof ParsedHTML) {
-// ((ParsedHTML) o).addToList( htmlElement );
-// return;
-// }
-// }
-// }
+ static class TableCellFactory extends HTMLElementFactory {
+ HTMLElement toHTMLElement( NodeUtils.PreOrderTraversal pot, ParsedHTML parsedHTML, Element element ) {
+ WebTable.TableRow tr = getTableRow( pot );
+ if (tr == null) return null;
+ return tr.newTableCell( element );
+ }
+ private WebTable.TableRow getTableRow( NodeUtils.PreOrderTraversal pot ) {
+ return (WebTable.TableRow) getClosestContext( pot, WebTable.TableRow.class );
+ }
+ protected boolean addToContext() { return true; }
+ protected void addToLists( NodeUtils.PreOrderTraversal pot, HTMLElement htmlElement ) {
+ getTableRow( pot ).addTableCell( (TableCell) htmlElement );
+ }
}
+
private static HashMap _htmlFactoryClasses = new HashMap();
static {
- _htmlFactoryClasses.put( "a", new WebLinkFactory() );
- _htmlFactoryClasses.put( "area", new WebLinkFactory() );
- _htmlFactoryClasses.put( "form", new WebFormFactory() );
- _htmlFactoryClasses.put( "img", new WebImageFactory() );
+ _htmlFactoryClasses.put( "a", new WebLinkFactory() );
+ _htmlFactoryClasses.put( "area", new WebLinkFactory() );
+ _htmlFactoryClasses.put( "form", new WebFormFactory() );
+ _htmlFactoryClasses.put( "img", new WebImageFactory() );
_htmlFactoryClasses.put( "applet", new WebAppletFactory() );
- _htmlFactoryClasses.put( "table", new WebTableFactory() );
+ _htmlFactoryClasses.put( "table", new WebTableFactory() );
+ _htmlFactoryClasses.put( "tr", new TableRowFactory() );
+ _htmlFactoryClasses.put( "td", new TableCellFactory() );
+ _htmlFactoryClasses.put( "th", new TableCellFactory() );
}
private static HTMLElementFactory getHTMLElementFactory( String tagName ) {
@@ -274,10 +317,11 @@
NodeUtils.NodeAction action = new NodeUtils.NodeAction() {
public boolean processElement( NodeUtils.PreOrderTraversal pot, Element element ) {
- if (_elements.containsKey( element )) return true;
-
HTMLElementFactory factory = getHTMLElementFactory( element.getNodeName().toLowerCase() );
- if (factory != null) factory.recordElement( pot, element, factory.toHTMLElement( ParsedHTML.this, element ) );
+ if (factory == null) return true;
+
+ if (!_elements.containsKey( element )) factory.recordElement( pot, element, ParsedHTML.this );
+ if (factory.addToContext()) pot.pushContext( _elements.get( element ) );
return true;
}
@@ -298,7 +342,12 @@
private WebLink toLinkAnchor( Element child ) {
- return (!isLinkAnchor( child )) ? null : new WebLink( _response, _baseURL, _baseTarget, child );
+ return (!isWebLink( child )) ? null : new WebLink( _response, _baseURL, _baseTarget, child );
+ }
+
+
+ private boolean isWebLink( Node node ) {
+ return (node.getAttributes().getNamedItem( "href" ) != null);
}
@@ -313,7 +362,6 @@
private WebTable toWebTable( Element element ) {
- if (!WebTable.isTopLevelTable( element, getRootNode() )) return null;
return new WebTable( _response, element, _baseURL, _baseTarget, _characterSet );
}
@@ -539,22 +587,6 @@
if (_rootNode == null) throw new IllegalStateException( "The root node has not been specified" );
return _rootNode;
}
-
-
-
- /**
- * Returns true if the node is a link anchor node.
- **/
- private boolean isLinkAnchor( Node node ) { // XXX do we really need all these tests any more?
- if (node.getNodeType() != Node.ELEMENT_NODE) {
- return false;
- } else if (!node.getNodeName().equalsIgnoreCase( "a" ) && !node.getNodeName().equalsIgnoreCase( "area" )) {
- return false;
- } else {
- return (node.getAttributes().getNamedItem( "href" ) != null);
- }
- }
-
/**
Index: TableCell.java
===================================================================
RCS file: /cvsroot/httpunit/httpunit/src/com/meterware/httpunit/TableCell.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- TableCell.java 1 Aug 2002 14:58:59 -0000 1.8
+++ TableCell.java 26 Dec 2002 15:33:56 -0000 1.9
@@ -19,6 +19,8 @@
* DEALINGS IN THE SOFTWARE.
*
*******************************************************************************************************************/
+import com.meterware.httpunit.scripting.ScriptableDelegate;
+
import java.net.URL;
import org.w3c.dom.Element;
@@ -28,7 +30,7 @@
/**
* A single cell in an HTML table.
**/
-public class TableCell extends ParsedHTML implements HTMLSegment {
+public class TableCell extends ParsedHTML implements HTMLSegment, HTMLElement {
/**
@@ -63,6 +65,46 @@
}
+//-------------------------------- HTMLElement methods ---------------------------------------
+
+
+ /**
+ * Returns the ID associated with this element. IDs are unique throughout the HTML document.
+ **/
+ public String getID() {
+ return getAttribute( "id" );
+ }
+
+
+ /**
+ * Returns the name associated with this element.
+ **/
+ public String getName() {
+ return getAttribute( "name" );
+ }
+
+
+ /**
+ * Returns the title associated with this element.
+ **/
+ public String getTitle() {
+ return getAttribute( "title" );
+ }
+
+
+ /**
+ * Returns the delegate which supports scripting this element.
+ */
+ public ScriptableDelegate getScriptableDelegate() {
+ throw new RuntimeException( "No scripting support for " + getClass().getName() );
+ }
+
+
+ private String getAttribute( final String name ) {
+ return NodeUtils.getNodeAttribute( _element, name );
+ }
+
+
//---------------------------------------- package methods -----------------------------------------
@@ -96,7 +138,6 @@
private int getAttributeValue( Node node, String attributeName, int defaultValue ) {
return NodeUtils.getAttributeValue( node, attributeName, defaultValue );
}
-
}
Index: WebForm.java
===================================================================
RCS file: /cvsroot/httpunit/httpunit/src/com/meterware/httpunit/WebForm.java,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -r1.71 -r1.72
--- WebForm.java 13 Dec 2002 12:59:41 -0000 1.71
+++ WebForm.java 26 Dec 2002 15:33:56 -0000 1.72
@@ -425,7 +425,7 @@
* Returns the scriptable delegate.
*/
- ScriptableDelegate getScriptableDelegate() {
+ public ScriptableDelegate getScriptableDelegate() {
return getScriptableObject();
}
Index: WebImage.java
===================================================================
RCS file: /cvsroot/httpunit/httpunit/src/com/meterware/httpunit/WebImage.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- WebImage.java 13 Oct 2002 23:53:48 -0000 1.8
+++ WebImage.java 26 Dec 2002 15:33:56 -0000 1.9
@@ -34,7 +34,6 @@
**/
public class WebImage extends FixedURLWebRequestSource {
- private URL _baseURL;
private Node _node;
private ParsedHTML _parsedHTML;
private Scriptable _scriptable;
@@ -44,7 +43,6 @@
WebImage( WebResponse response, ParsedHTML parsedHTML, URL baseURL, Node node, String parentTarget ) {
super( response, node, baseURL, NodeUtils.getNodeAttribute( node, "src" ), parentTarget );
- _baseURL = baseURL;
_node = node;
_parsedHTML = parsedHTML;
_src = NodeUtils.getNodeAttribute( _node, "src" );
@@ -125,7 +123,7 @@
* Returns the scriptable delegate.
*/
- ScriptableDelegate getScriptableDelegate() {
+ public ScriptableDelegate getScriptableDelegate() {
return getScriptableObject();
}
}
Index: WebLink.java
===================================================================
RCS file: /cvsroot/httpunit/httpunit/src/com/meterware/httpunit/WebLink.java,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- WebLink.java 17 Nov 2002 13:57:47 -0000 1.36
+++ WebLink.java 26 Dec 2002 15:33:56 -0000 1.37
@@ -142,7 +142,7 @@
/**
* Returns the scriptable delegate.
*/
- ScriptableDelegate getScriptableDelegate() {
+ public ScriptableDelegate getScriptableDelegate() {
return getScriptableObject();
}
Index: WebTable.java
===================================================================
RCS file: /cvsroot/httpunit/httpunit/src/com/meterware/httpunit/WebTable.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- WebTable.java 26 Dec 2002 04:59:35 -0000 1.22
+++ WebTable.java 26 Dec 2002 15:33:56 -0000 1.23
@@ -28,7 +28,7 @@
/**
* This class represents a table in an HTML page.
*
- * @author <a href="mailto:rus...@ac...">Russell Gold</a>
+ * @author <a href="mailto:rus...@ht...">Russell Gold</a>
* @author <a href="mailto:bx...@bi...">Benoit Xhenseval</a>
**/
public class WebTable extends HTMLElementBase {
@@ -51,8 +51,14 @@
* Returns the number of rows in the table.
**/
public int getRowCount() {
+ return getCells().length;
+ }
+
+
+ private TableCell[][] getCells() {
if (_cells == null) readTable();
- return _cells.length;
+ return _cells;
+
}
@@ -60,9 +66,8 @@
* Returns the number of columns in the table.
**/
public int getColumnCount() {
- if (_cells == null) readTable();
- if (_cells.length == 0) return 0;
- return _cells[0].length;
+ if (getCells().length == 0) return 0;
+ return getCells()[0].length;
}
@@ -94,8 +99,7 @@
* @throws IndexOutOfBoundsException if the specified cell numbers are not valid
**/
public TableCell getTableCell( int row, int column ) {
- if (_cells == null) readTable();
- return _cells[ row ][ column ];
+ return getCells()[ row ][ column ];
}
@@ -104,14 +108,10 @@
* @return TableCell with given ID or null if ID is not found.
**/
public TableCell getTableCellWithID( String id ) {
- if (_cells == null) readTable();
- String idToCompare;
for (int i = 0; i < getRowCount(); i++) {
for (int j = 0; j < getColumnCount(); j++) {
- if (_cells[i][j]!=null) {
- idToCompare = NodeUtils.getNodeAttribute( _cells[i][j].getOriginalDOM(), "id" );
- if (HttpUnitUtils.matches( id, idToCompare )) return _cells[i][j];
- }
+ final TableCell tableCell = getCells()[i][j];
+ if (tableCell!=null && tableCell.getID().equals( id )) return tableCell;
}
}
return null;
@@ -209,16 +209,15 @@
public String toString() {
String eol = System.getProperty( "line.separator" );
- if (_cells == null) readTable();
StringBuffer sb = new StringBuffer( HttpUnitUtils.DEFAULT_TEXT_BUFFER_SIZE).append("WebTable:" ).append( eol );
- for (int i = 0; i < _cells.length; i++) {
+ for (int i = 0; i < getCells().length; i++) {
sb.append( "[" ).append( i ).append( "]: " );
- for (int j = 0; j < _cells[i].length; j++) {
+ for (int j = 0; j < getCells()[i].length; j++) {
sb.append( " [" ).append( j ).append( "]=" );
- if (_cells[i][j] == null) {
+ if (getCells()[i][j] == null) {
sb.append( "null" );
} else {
- sb.append( _cells[i][j].asText() );
+ sb.append( getCells()[i][j].asText() );
}
}
sb.append( eol );
@@ -284,106 +283,56 @@
}
-
private void placeCell( int row, int column, TableCell cell ) {
while (_cells[ row ][ column ] != null) column++;
_cells[ row ][ column ] = cell;
}
- /**
- * Returns true if the specified table node is not nested within another one.
- **/
- static boolean isTopLevelTable( Node tableNode, Node root ) {
- return isMoreCloselyNested( tableNode, root, "table" );
- }
+ private ArrayList _rows = new ArrayList();
- /**
- * Returns true if the desiredParentTag is found in the tree above this node more closely nested than
- * the undesiredParentTag, or if the top of the tree is found before the undesired tag.
- **/
- private static boolean isMoreCloselyNested( Node node, Node desiredParentNode, String undesiredParentTag ) {
- node = node.getParentNode();
- while (true) {
- if (node == desiredParentNode) {
- return true;
- } else if (node.getNodeName().equalsIgnoreCase( undesiredParentTag )) {
- return false;
- } else if (node.getParentNode() == null) {
- return true;
- }
- node = node.getParentNode();
- }
+ void addRow( TableRow tableRow ) {
+ _cells = null;
+ _rows.add( tableRow );
}
+ TableRow newTableRow( Element element ) {
+ return new TableRow( element );
+ }
+
private TableRow[] getRows() {
- final Vector rows = new Vector();
+ return (TableRow[]) _rows.toArray( new TableRow[ _rows.size() ] );
+ }
- processChildren( _dom, "table", new ElementHandler() {
- public void handleElement( Element element ) {
- rows.addElement( new TableRow( element ) );
- }
- public boolean shouldHandleElement( String tagName ) {
- return tagName.equalsIgnoreCase( "tr" );
- }
- } );
- TableRow[] result = new TableRow[ rows.size() ];
- rows.copyInto( result );
- return result;
- }
+ class TableRow extends HTMLElementBase {
+ private ArrayList _cells = new ArrayList();
- class TableRow {
- Element getElement() {
- return _element;
+ TableRow( Element rowNode ) {
+ super( rowNode );
}
+
TableCell[] getCells() {
- final Vector cells = new Vector();
+ return (TableCell[]) _cells.toArray( new TableCell[ _cells.size() ]);
+ }
- processChildren( _element, "table", new ElementHandler() {
- public void handleElement( Element element ) {
- cells.addElement( new TableCell( _response, element, _url, _parentTarget, _characterSet ) );
- }
- public boolean shouldHandleElement( String tagName ) {
- return tagName.equalsIgnoreCase( "th" ) || tagName.equalsIgnoreCase( "td" );
- }
- } );
- TableCell[] result = new TableCell[ cells.size() ];
- cells.copyInto( result );
- return result;
+ TableCell newTableCell( Element element ) {
+ return new TableCell( _response, element, _url, _parentTarget, _characterSet );
}
- private Element _element;
- TableRow( Element rowNode ) {
- _element = rowNode;
+ void addTableCell( TableCell cell ) {
+ _cells.add( cell );
}
- }
-
- interface ElementHandler {
- public void handleElement( Element element );
- public boolean shouldHandleElement( String tagName );
}
-
- static void processChildren( Element root, String avoidingParentTag, ElementHandler handler ) {
-
- for (Node child = root.getFirstChild(); child != null; child = child.getNextSibling()) {
- if (child instanceof Element) {
- Element element = (Element) child;
- String name = child.getNodeName();
- if (handler.shouldHandleElement( name )) handler.handleElement( element );
- if (!name.equalsIgnoreCase( avoidingParentTag )) processChildren( element, avoidingParentTag, handler );
- }
- }
- }
static {
MATCH_FIRST_NONBLANK_CELL = new HTMLElementPredicate() { // XXX find a way to do this w/o purging the table cells
|