KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > gargoylesoftware > htmlunit > html > HtmlTable


1 /*
2  * Copyright (c) 2002, 2005 Gargoyle Software Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12  * 3. The end-user documentation included with the redistribution, if any, must
13  * include the following acknowledgment:
14  *
15  * "This product includes software developed by Gargoyle Software Inc.
16  * (http://www.GargoyleSoftware.com/)."
17  *
18  * Alternately, this acknowledgment may appear in the software itself, if
19  * and wherever such third-party acknowledgments normally appear.
20  * 4. The name "Gargoyle Software" must not be used to endorse or promote
21  * products derived from this software without prior written permission.
22  * For written permission, please contact info@GargoyleSoftware.com.
23  * 5. Products derived from this software may not be called "HtmlUnit", nor may
24  * "HtmlUnit" appear in their name, without prior written permission of
25  * Gargoyle Software Inc.
26  *
27  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
28  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
30  * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
33  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
36  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */

38 package com.gargoylesoftware.htmlunit.html;
39
40 import java.util.ArrayList JavaDoc;
41 import java.util.Collections JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.util.List JavaDoc;
44 import java.util.Map JavaDoc;
45 import java.util.NoSuchElementException JavaDoc;
46
47 import com.gargoylesoftware.htmlunit.ElementNotFoundException;
48
49 /**
50  * Wrapper for the html element "table"
51  *
52  * @version $Revision: 100 $
53  * @author <a HREF="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
54  * @author David K. Taylor
55  * @author <a HREF="mailto:cse@dynabean.de">Christian Sell</a>
56  */

57 public class HtmlTable extends ClickableElement {
58
59     /** the HTML tag represented by this element */
60     public static final String JavaDoc TAG_NAME = "table";
61
62     /**
63      * Create an instance
64      *
65      * @param page The page that contains this element
66      * @param attributes the initial attributes
67      */

68     public HtmlTable( final HtmlPage page, final Map JavaDoc attributes ) {
69         super( page, attributes );
70     }
71
72     /**
73      * @return the HTML tag name
74      */

75     public String JavaDoc getTagName() {
76         return TAG_NAME;
77     }
78
79     /**
80      * Return the first cell that matches the specified row and column,
81      * searching left to right, top to bottom.
82      *
83      * @param rowIndex The row index
84      * @param columnIndex The column index
85      * @return The HtmlTableCell at that location or null if there are no cells
86      * at that location
87      */

88     public final HtmlTableCell getCellAt( final int rowIndex, final int columnIndex )
89     {
90         final RowIterator rowIterator = getRowIterator();
91         for(int rowNo = 0; rowIterator.hasNext(); rowNo++) {
92             final HtmlTableRow row = rowIterator.nextRow();
93
94             final HtmlTableRow.CellIterator cellIterator = row.getCellIterator();
95             for(int colNo = 0; cellIterator.hasNext(); colNo++) {
96                 final HtmlTableCell cell = cellIterator.nextCell();
97                 if(rowNo + cell.getRowSpan() > rowIndex) {
98                     if(colNo <= columnIndex && colNo + cell.getColumnSpan() > columnIndex) {
99                         return cell;
100                     }
101                 }
102             }
103         }
104         return null;
105     }
106
107     /**
108      * @return an iterator over all the HtmlTableRow objects
109      */

110     private RowIterator getRowIterator() {
111         return new RowIterator();
112     }
113
114     /**
115      * @return an immutable list containing all the HtmlTableRow objects
116      * @see #getRowIterator
117      */

118     public List JavaDoc getRows() {
119         final List JavaDoc result = new ArrayList JavaDoc();
120         for(final RowIterator iterator = getRowIterator(); iterator.hasNext(); ) {
121             result.add(iterator.next());
122         }
123         return Collections.unmodifiableList(result);
124     }
125
126     /**
127      * @param index the 0-based index of the row
128      * @return the HtmlTableRow at the given index
129      * @throws IndexOutOfBoundsException if there is no row at the given index
130      * @see #getRowIterator
131      */

132     public HtmlTableRow getRow(final int index) throws IndexOutOfBoundsException JavaDoc {
133         int count = 0;
134         for(final RowIterator iterator = getRowIterator(); iterator.hasNext(); count++) {
135             final HtmlTableRow next = iterator.nextRow();
136             if(count == index) {
137                 return next;
138             }
139         }
140         throw new IndexOutOfBoundsException JavaDoc();
141     }
142
143     /**
144      * compute the number of rows in this table. Note that the count is computed dynamically
145      * by iterating over all rows
146      *
147      * @return The number of rows in this table
148      */

149     public final int getRowCount() {
150         int count = 0;
151         for(final RowIterator iterator = getRowIterator(); iterator.hasNext(); iterator.next()) {
152             count++;
153         }
154         return count;
155     }
156
157
158     /**
159      * Find and return the row with the specified id.
160      *
161      * @param id The id of the row
162      * @return The row with the specified id.
163      * @exception ElementNotFoundException If the row cannot be found.
164      */

165     public final HtmlTableRow getRowById( final String JavaDoc id ) throws ElementNotFoundException {
166         final RowIterator iterator = new RowIterator();
167         while( iterator.hasNext() ) {
168             final HtmlTableRow row = (HtmlTableRow)iterator.next();
169             if( row.getIdAttribute().equals(id) ) {
170                 return row;
171             }
172         }
173         throw new ElementNotFoundException( "tr", "id", id );
174     }
175
176
177     /**
178      * Return the table caption text or an empty string if a caption wasn't specified
179      *
180      * @return The caption text
181      */

182     public String JavaDoc getCaptionText() {
183         final Iterator JavaDoc iterator = getChildElementsIterator();
184         while( iterator.hasNext() ) {
185             final HtmlElement element = (HtmlElement)iterator.next();
186             if( element instanceof HtmlCaption ) {
187                 return element.asText();
188             }
189         }
190         return null;
191     }
192
193
194     /**
195      * Return the table header or null if a header wasn't specified
196      *
197      * @return The table header
198      */

199     public HtmlTableHeader getHeader() {
200         final Iterator JavaDoc iterator = getChildElementsIterator();
201         while( iterator.hasNext() ) {
202             final HtmlElement element = (HtmlElement)iterator.next();
203             if( element instanceof HtmlTableHeader ) {
204                 return (HtmlTableHeader)element;
205             }
206         }
207         return null;
208     }
209
210
211     /**
212      * Return the table footer or null if a footer wasn't specified
213      *
214      * @return The table footer
215      */

216     public HtmlTableFooter getFooter() {
217         final Iterator JavaDoc iterator = getChildElementsIterator();
218         while( iterator.hasNext() ) {
219             final HtmlElement element = (HtmlElement)iterator.next();
220             if( element instanceof HtmlTableFooter ) {
221                 return (HtmlTableFooter)element;
222             }
223         }
224         return null;
225     }
226
227
228     /**
229      * Return a list of tables bodies defined in this table. If no bodies were defined
230      * then an empty list will be returned.
231      *
232      * @return A list of {@link com.gargoylesoftware.htmlunit.html.HtmlTableBody} objects.
233      */

234     public List JavaDoc getBodies() {
235         final List JavaDoc bodies = new ArrayList JavaDoc();
236         final Iterator JavaDoc iterator = getChildElementsIterator();
237         while( iterator.hasNext() ) {
238             final HtmlElement element = (HtmlElement)iterator.next();
239             if( element instanceof HtmlTableBody ) {
240                 bodies.add( element );
241             }
242         }
243         return bodies;
244     }
245
246
247     /**
248      * Return the value of the attribute "summary". Refer to the
249      * <a HREF='http://www.w3.org/TR/html401/'>HTML 4.01</a>
250      * documentation for details on the use of this attribute.
251      *
252      * @return The value of the attribute "summary"
253      * or an empty string if that attribute isn't defined.
254      */

255     public final String JavaDoc getSummaryAttribute() {
256         return getAttributeValue("summary");
257     }
258
259
260     /**
261      * Return the value of the attribute "width". Refer to the
262      * <a HREF='http://www.w3.org/TR/html401/'>HTML 4.01</a>
263      * documentation for details on the use of this attribute.
264      *
265      * @return The value of the attribute "width"
266      * or an empty string if that attribute isn't defined.
267      */

268     public final String JavaDoc getWidthAttribute() {
269         return getAttributeValue("width");
270     }
271
272
273     /**
274      * Return the value of the attribute "border". Refer to the
275      * <a HREF='http://www.w3.org/TR/html401/'>HTML 4.01</a>
276      * documentation for details on the use of this attribute.
277      *
278      * @return The value of the attribute "border"
279      * or an empty string if that attribute isn't defined.
280      */

281     public final String JavaDoc getBorderAttribute() {
282         return getAttributeValue("border");
283     }
284
285
286     /**
287      * Return the value of the attribute "frame". Refer to the
288      * <a HREF='http://www.w3.org/TR/html401/'>HTML 4.01</a>
289      * documentation for details on the use of this attribute.
290      *
291      * @return The value of the attribute "frame"
292      * or an empty string if that attribute isn't defined.
293      */

294     public final String JavaDoc getFrameAttribute() {
295         return getAttributeValue("frame");
296     }
297
298
299     /**
300      * Return the value of the attribute "rules". Refer to the
301      * <a HREF='http://www.w3.org/TR/html401/'>HTML 4.01</a>
302      * documentation for details on the use of this attribute.
303      *
304      * @return The value of the attribute "rules"
305      * or an empty string if that attribute isn't defined.
306      */

307     public final String JavaDoc getRulesAttribute() {
308         return getAttributeValue("rules");
309     }
310
311
312     /**
313      * Return the value of the attribute "cellspacing". Refer to the
314      * <a HREF='http://www.w3.org/TR/html401/'>HTML 4.01</a>
315      * documentation for details on the use of this attribute.
316      *
317      * @return The value of the attribute "cellspacing"
318      * or an empty string if that attribute isn't defined.
319      */

320     public final String JavaDoc getCellSpacingAttribute() {
321         return getAttributeValue("cellspacing");
322     }
323
324
325     /**
326      * Return the value of the attribute "cellpadding". Refer to the
327      * <a HREF='http://www.w3.org/TR/html401/'>HTML 4.01</a>
328      * documentation for details on the use of this attribute.
329      *
330      * @return The value of the attribute "cellpadding"
331      * or an empty string if that attribute isn't defined.
332      */

333     public final String JavaDoc getCellPaddingAttribute() {
334         return getAttributeValue("cellpadding");
335     }
336
337
338     /**
339      * Return the value of the attribute "align". Refer to the
340      * <a HREF='http://www.w3.org/TR/html401/'>HTML 4.01</a>
341      * documentation for details on the use of this attribute.
342      *
343      * @return The value of the attribute "align"
344      * or an empty string if that attribute isn't defined.
345      */

346     public final String JavaDoc getAlignAttribute() {
347         return getAttributeValue("align");
348     }
349
350
351     /**
352      * Return the value of the attribute "bgcolor". Refer to the
353      * <a HREF='http://www.w3.org/TR/html401/'>HTML 4.01</a>
354      * documentation for details on the use of this attribute.
355      *
356      * @return The value of the attribute "bgcolor"
357      * or an empty string if that attribute isn't defined.
358      */

359     public final String JavaDoc getBgcolorAttribute() {
360         return getAttributeValue("bgcolor");
361     }
362
363
364     /**
365      * an iterator that moves over all rows in tis table. The iterator will also
366      * enter into nested row group elements (header, footer and body)
367      */

368     private class RowIterator implements Iterator JavaDoc {
369
370         private HtmlTableRow nextRow_;
371         private TableRowGroup currentGroup_;
372
373         /** create a new instance */
374         public RowIterator() {
375             setNextRow(getFirstChild());
376         }
377
378         /**
379          * @return <code>true</code> if there are more rows available
380          */

381         public boolean hasNext() {
382             return nextRow_ != null;
383         }
384
385         /**
386          * @return the next row from this iterator
387          * @throws NoSuchElementException if no more rows are available
388          */

389         public Object JavaDoc next() throws NoSuchElementException JavaDoc {
390             return nextRow();
391         }
392
393         /**
394          * remove the current row from the underlying table
395          * @throws IllegalStateException if there is no current element
396          */

397         public void remove() throws IllegalStateException JavaDoc {
398             if(nextRow_ == null) {
399                 throw new IllegalStateException JavaDoc();
400             }
401             if(nextRow_.getPreviousSibling() != null) {
402                 nextRow_.getPreviousSibling().remove();
403             }
404         }
405
406         /**
407          * @return the next row from this iterator
408          * @throws NoSuchElementException if no more rows are available
409          */

410         public HtmlTableRow nextRow() throws NoSuchElementException JavaDoc {
411             if(nextRow_ != null) {
412                 final HtmlTableRow result = nextRow_;
413                 setNextRow(nextRow_.getNextSibling());
414                 return result;
415             }
416             else {
417                 throw new NoSuchElementException JavaDoc();
418             }
419         }
420
421         /**
422          * set the internal position to the next row, starting at the given node
423          * @param node the node to marik as the next row. If this is not a row, the
424          * next reachable row will be marked
425          */

426         private void setNextRow(final DomNode node) {
427
428             nextRow_ = null;
429             for(DomNode next = node; next != null; next = next.getNextSibling()) {
430                 if(next instanceof HtmlTableRow) {
431                     nextRow_ = (HtmlTableRow)next;
432                     return;
433                 }
434                 else if(currentGroup_ == null && next instanceof TableRowGroup) {
435                     currentGroup_ = (TableRowGroup)next;
436                     setNextRow(next.getFirstChild());
437                     return;
438                 }
439             }
440             if(currentGroup_ != null) {
441                 final DomNode group = currentGroup_;
442                 currentGroup_ = null;
443                 setNextRow(group.getNextSibling());
444             }
445         }
446     }
447 }
448
Popular Tags