1 57 package org.enhydra.xml.lazydom.html; 58 import org.w3c.dom.Element ; 59 import org.w3c.dom.Node ; 60 import org.w3c.dom.html.HTMLAnchorElement; 61 import org.w3c.dom.html.HTMLAppletElement; 62 import org.w3c.dom.html.HTMLAreaElement; 63 import org.w3c.dom.html.HTMLCollection; 64 import org.w3c.dom.html.HTMLElement; 65 import org.w3c.dom.html.HTMLFormElement; 66 import org.w3c.dom.html.HTMLImageElement; 67 import org.w3c.dom.html.HTMLObjectElement; 68 import org.w3c.dom.html.HTMLOptionElement; 69 import org.w3c.dom.html.HTMLTableCellElement; 70 import org.w3c.dom.html.HTMLTableRowElement; 71 import org.w3c.dom.html.HTMLTableSectionElement; 72 73 74 99 class HTMLCollectionImpl 100 implements HTMLCollection 101 { 102 103 104 108 static final short ANCHOR = 1; 109 110 111 114 static final short FORM = 2; 115 116 117 120 static final short IMAGE = 3; 121 122 123 127 static final short APPLET = 4; 128 129 130 134 static final short LINK = 5; 135 136 137 141 static final short OPTION = 6; 142 143 144 148 static final short ROW = 7; 149 150 151 156 static final short ELEMENT = 8; 157 158 159 163 static final short AREA = -1; 164 165 166 170 static final short TBODY = -2; 171 172 173 177 static final short CELL = -3; 178 179 180 185 private short _lookingFor; 186 187 188 191 private Element _topLevel; 192 193 194 202 HTMLCollectionImpl( HTMLElement topLevel, short lookingFor ) 203 { 204 if ( topLevel == null ) 205 throw new NullPointerException ( "HTM011 Argument 'topLevel' is null." ); 206 _topLevel = topLevel; 207 _lookingFor = lookingFor; 208 } 209 210 211 217 public final int getLength() 218 { 219 return getLength( _topLevel ); 221 } 222 223 224 232 public final Node item( int index ) 233 { 234 if ( index < 0 ) 235 throw new IllegalArgumentException ( "HTM012 Argument 'index' is negative." ); 236 return item( _topLevel, new CollectionIndex( index ) ); 238 } 239 240 241 250 public final Node namedItem( String name ) 251 { 252 if ( name == null ) 253 throw new NullPointerException ( "HTM013 Argument 'name' is null." ); 254 return namedItem( _topLevel, name ); 256 } 257 258 259 267 private int getLength( Element topLevel ) 268 { 269 int length; 270 Node node; 271 272 synchronized ( topLevel ) 273 { 274 length = 0; 277 node = topLevel.getFirstChild(); 278 while ( node != null ) 279 { 280 if ( node instanceof Element ) 285 { 286 if ( collectionMatch( (Element ) node, null ) ) 287 ++ length; 288 else if ( recurse() ) 289 length += getLength( (Element ) node ); 290 } 291 node = node.getNextSibling(); 292 } 293 } 294 return length; 295 } 296 297 298 314 private Node item( Element topLevel, CollectionIndex index ) 315 { 316 Node node; 317 Node result; 318 319 synchronized ( topLevel ) 320 { 321 node = topLevel.getFirstChild(); 325 while ( node != null ) 326 { 327 if ( node instanceof Element ) 332 { 333 if ( collectionMatch( (Element ) node, null ) ) 334 { 335 if ( index.isZero() ) 336 return node; 337 index.decrement(); 338 } else if ( recurse() ) 339 { 340 result = item( (Element ) node, index ); 341 if ( result != null ) 342 return result; 343 } 344 } 345 node = node.getNextSibling(); 346 } 347 } 348 return null; 349 } 350 351 352 360 private Node namedItem( Element topLevel, String name ) 361 { 362 Node node; 363 Node result; 364 365 synchronized ( topLevel ) 366 { 367 node = topLevel.getFirstChild(); 370 while ( node != null ) 371 { 372 if ( node instanceof Element ) 377 { 378 if ( collectionMatch( (Element ) node, name ) ) 379 return node; 380 else if ( recurse() ) 381 { 382 result = namedItem( (Element ) node, name ); 383 if ( result != null ) 384 return result; 385 } 386 } 387 node = node.getNextSibling(); 388 } 389 return node; 390 } 391 } 392 393 394 402 protected boolean recurse() 403 { 404 return _lookingFor > 0; 405 } 406 407 408 419 protected boolean collectionMatch( Element elem, String name ) 420 { 421 boolean match; 422 423 synchronized ( elem ) 424 { 425 match = false; 430 switch ( _lookingFor ) 431 { 432 case ANCHOR: 433 match = ( elem instanceof HTMLAnchorElement ) && 436 elem.getAttribute( "name" ).length() > 0; 437 break; 438 case FORM: 439 match = ( elem instanceof HTMLFormElement ); 441 break; 442 case IMAGE: 443 match = ( elem instanceof HTMLImageElement ); 445 break; 446 case APPLET: 447 match = ( elem instanceof HTMLAppletElement ) || 451 ( elem instanceof HTMLObjectElement && 452 ( "application/java".equals( elem.getAttribute( "codetype" ) ) || 453 elem.getAttribute( "classid" ).startsWith( "java:" ) ) ); 454 break; 455 case ELEMENT: 456 match = ( elem instanceof HTMLFormControl ); 458 break; 459 case LINK: 460 match = ( ( elem instanceof HTMLAnchorElement || 462 elem instanceof HTMLAreaElement ) && 463 elem.getAttribute( "href" ).length() > 0 ); 464 break; 465 case AREA: 466 match = ( elem instanceof HTMLAreaElement ); 468 break; 469 case OPTION: 470 match = ( elem instanceof HTMLOptionElement ); 472 break; 473 case ROW: 474 match = ( elem instanceof HTMLTableRowElement ); 476 break; 477 case TBODY: 478 match = ( elem instanceof HTMLTableSectionElement && 480 elem.getTagName().equals( "tbody" ) ); 481 break; 482 case CELL: 483 match = ( elem instanceof HTMLTableCellElement ); 485 break; 486 } 487 488 if ( match && name != null ) 492 { 493 if ( elem instanceof HTMLAnchorElement && 496 name.equals( elem.getAttribute( "name" ) ) ) 497 return true; 498 match = name.equals( elem.getAttribute( "id" ) ); 499 } 500 } 501 return match; 502 } 503 504 505 } 506 507 508 517 class CollectionIndex 518 { 519 520 521 526 int getIndex() 527 { 528 return _index; 529 } 530 531 532 535 void decrement() 536 { 537 -- _index; 538 } 539 540 541 546 boolean isZero() 547 { 548 return _index <= 0; 549 } 550 551 552 558 CollectionIndex( int index ) 559 { 560 _index = index; 561 } 562 563 564 567 private int _index; 568 569 570 } 571 | Popular Tags |