KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > xml > dom > html > HTMLCollectionImpl


1 /**
2  * org/ozone-db/xml/dom/html/HTMLCollectionImpl.java
3  *
4  * The contents of this file are subject to the OpenXML Public
5  * License Version 1.0; you may not use this file except in compliance
6  * with the License. You may obtain a copy of the License at
7  * http://www.openxml.org/license.html
8  *
9  * THIS SOFTWARE IS DISTRIBUTED ON AN "AS IS" BASIS WITHOUT WARRANTY
10  * OF ANY KIND, EITHER EXPRESSED OR IMPLIED. THE INITIAL DEVELOPER
11  * AND ALL CONTRIBUTORS SHALL NOT BE LIABLE FOR ANY DAMAGES AS A
12  * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
13  * DERIVATIVES. SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING
14  * RIGHTS AND LIMITATIONS UNDER THE LICENSE.
15  *
16  * The Initial Developer of this code under the License is Assaf Arkin.
17  * Portions created by Assaf Arkin are Copyright (C) 1998, 1999.
18  * All Rights Reserved.
19  */

20
21 package org.ozoneDB.xml.dom.html;
22
23 import org.ozoneDB.xml.dom.CollectionImpl;
24 import org.w3c.dom.Element JavaDoc;
25 import org.w3c.dom.html.*;
26
27
28 /**
29  * Implements {@link org.w3c.dom.html.HTMLCollection} to traverse any named
30  * elements on a {@link org.w3c.dom.html.HTMLDocument}. The elements type to
31  * look for is identified in the constructor by code. This collection is not
32  * optimized for traversing large trees.
33  * <p>
34  * The collection has to meet two requirements: it has to be live, and it has
35  * to traverse depth first and always return results in that order. As such,
36  * using an object container (such as {@link java.util.Vector}) is expensive on
37  * insert/remove operations. Instead, the collection has been implemented using
38  * three traversing functions. As a result, operations on large documents will
39  * result in traversal of the entire document tree and consume a considerable
40  * amount of time.
41  * <p>
42  * Note that synchronization on the traversed document cannot be achieved.
43  * The document itself cannot be locked, and locking each traversed node is
44  * likely to lead to a dead lock condition. Therefore, there is a chance of the
45  * document being changed as results are fetched; in all likelihood, the results
46  * might be out dated, but not erroneous.
47  *
48  *
49  * @version $Revision: 1.2 $ $Date: 2003/11/20 23:18:42 $
50  * @author <a HREF="mailto:arkin@trendline.co.il">Assaf Arkin</a>
51  * @see org.w3c.dom.html.HTMLCollection
52  * @see org.ozoneDB.xml.dom.CollectionImpl
53  */

54 final class HTMLCollectionImpl extends CollectionImpl implements HTMLCollection {
55
56
57     /**
58      * Returns true if scanning methods should iterate through the collection.
59      * When looking for elements in the document, recursing is needed to traverse
60      * the full document tree. When looking inside a specific element (e.g. for a
61      * cell inside a row), recursing can lead to erroneous results.
62      *
63      * @return True if methods should recurse to traverse entire tree
64      */

65     protected boolean recurse() {
66         return _lookingFor > 0;
67     }
68
69
70     /**
71      * Determines if current element matches based on what we're looking for.
72      * The element is passed along with an optional identifier name. If the
73      * element is the one we're looking for, return true. If the name is also
74      * specified, the name must match the <code>id</code> attribute
75      * (match <code>name</code> first for anchors).
76      *
77      * @param elem The current element
78      * @param name The identifier name or null
79      * @return The element matches what we're looking for
80      */

81     protected boolean collectionMatch( Element JavaDoc elem, String JavaDoc name ) {
82         boolean match;
83
84         synchronized (elem) {
85             // Begin with no matching. Depending on what we're looking for,
86
// attempt to match based on the element type. This is the quickest
87
// way to match involving only a cast. Do the expensive string
88
// comparison later on.
89
match = false;
90             switch (_lookingFor) {
91             case ANCHOR:
92                 // Anchor is an <A> element with a 'name' attribute. Otherwise, it's
93
// just a link.
94
match = elem instanceof HTMLAnchorElement && elem.getAttribute( "name" ) != null;
95                 break;
96             case FORM:
97                 // Any <FORM> element.
98
match = elem instanceof HTMLFormElement;
99                 break;
100             case IMAGE:
101                 // Any <IMG> element. <OBJECT> elements with images are not returned.
102
match = elem instanceof HTMLImageElement;
103                 break;
104             case APPLET:
105                 // Any <APPLET> element, and any <OBJECT> element which represents an
106
// Applet. This is determined by 'codetype' attribute being
107
// 'application/java' or 'classid' attribute starting with 'java:'.
108
match = elem instanceof HTMLAppletElement || elem instanceof HTMLObjectElement
109                         && ("application/java".equals( elem.getAttribute( "codetype" ) ) || elem.getAttribute(
110                         "classid" ) != null && elem.getAttribute( "classid" ).startsWith( "java:" ));
111                 break;
112             case ELEMENT:
113                 // All form elements implement HTMLFormControl for easy identification.
114
match = elem instanceof HTMLFormControl;
115                 break;
116             case LINK:
117                 // Any <A> element, and any <AREA> elements with an 'href' attribute.
118
match = (elem instanceof HTMLAnchorElement || elem instanceof HTMLAreaElement) && elem.getAttribute(
119                         "href" ) != null;
120                 break;
121             case AREA:
122                 // Any <AREA> element.
123
match = elem instanceof HTMLAreaElement;
124                 break;
125             case OPTION:
126                 // Any <OPTION> element.
127
match = elem instanceof HTMLOptionElement;
128                 break;
129             case ROW:
130                 // Any <TR> element.
131
match = elem instanceof HTMLTableRowElement;
132                 break;
133             case TBODY:
134                 // Any <TBODY> element (one of three table section types).
135
match = elem instanceof HTMLTableSectionElement && elem.getTagName().equals( "tbody" );
136                 break;
137             case CELL:
138                 // Any <TD> element.
139
match = elem instanceof HTMLTableCellElement;
140                 break;
141             }
142
143             // If element type was matched and a name was specified, must also match
144
// the name against either the 'id' or the 'name' attribute. The 'name'
145
// attribute is relevant only for <A> elements for backward compatibility.
146
if (match && name != null) {
147                 // If an anchor and 'name' attribute matches, return true. Otherwise,
148
// try 'id' attribute.
149
if (elem instanceof HTMLAnchorElement && name.equals( elem.getAttribute( "name" ) )) {
150                     return true;
151                 }
152                 match = name.equals( elem.getAttribute( "id" ) );
153             }
154         }
155         return match;
156     }
157
158
159     /**
160      * Construct a new collection that retrieves element of the specific type
161      * (<code>lookingFor</code>) from the specific document portion
162      * (<code>topLevel</code>).
163      *
164      * @param topLevel The element underneath which the collection exists
165      * @param lookingFor Code indicating what elements to look for
166      */

167     HTMLCollectionImpl( HTMLElement topLevel, short lookingFor ) {
168         super( topLevel );
169         _lookingFor = lookingFor;
170     }
171
172
173     /**
174      * Request collection of all anchors in document: &lt;A&gt; elements that
175      * have a <code>name</code> attribute.
176      */

177     final static short ANCHOR = 1;
178
179
180     /**
181      * Request collection of all forms in document: &lt;FORM&gt; elements.
182      */

183     final static short FORM = 2;
184
185
186     /**
187      * Request collection of all images in document: &lt;IMAGE&gt; elements.
188      */

189     final static short IMAGE = 3;
190
191
192     /**
193      * Request collection of all Applets in document: &lt;APPLET&gt; and
194      * &lt;OBJECT&gt; elements (&lt;OBJECT&gt; must contain an Applet).
195      */

196     final static short APPLET = 4;
197
198
199     /**
200      * Request collection of all links in document: &lt;A&gt; and &lt;AREA&gt;
201      * elements (must have a <code>href</code> attribute).
202      */

203     final static short LINK = 5;
204
205
206     /**
207      * Request collection of all options in selection: &lt;OPTION&gt; elments in
208      * &lt;SELECT&gt; or &lt;OPTGROUP&gt;.
209      */

210     final static short OPTION = 6;
211
212
213     /**
214      * Request collection of all rows in table: &lt;TR&gt; elements in table or
215      * table section.
216      */

217     final static short ROW = 7;
218
219
220     /**
221      * Request collection of all form elements: &lt;INPUT&gt;, &lt;BUTTON&gt;,
222      * &lt;SELECT&gt;, &lt;TEXT&gt; and &lt;TEXTAREA&gt; elements inside form
223      * &lt;FORM&gt;.
224      */

225     final static short ELEMENT = 8;
226
227
228     /**
229      * Request collection of all areas in map: &lt;AREA&gt; element in &lt;MAP&gt;
230      * (non recursive).
231      */

232     final static short AREA = -1;
233
234
235     /**
236      * Request collection of all table bodies in table: &lt;TBODY&gt; element in
237      * table &lt;TABLE&gt; (non recursive).
238      */

239     final static short TBODY = -2;
240
241
242     /**
243      * Request collection of all cells in row: &lt;TD&gt; elements in &lt;TR&gt;
244      * (non recursive).
245      */

246     final static short CELL = -3;
247
248
249     /**
250      * Indicates what this collection is looking for. Holds one of the enumerated
251      * values and used by {@link #collectionMatch}. Set by the constructor and
252      * determine the collection's use for its life time.
253      */

254     private short _lookingFor;
255
256
257 }
258
Popular Tags