1 57 58 59 63 64 package org.enhydra.apache.xml.serialize; 65 66 67 import java.io.BufferedReader ; 68 import java.io.InputStream ; 69 import java.io.InputStreamReader ; 70 import java.util.Hashtable ; 71 72 73 87 public final class HTMLdtd 88 { 89 90 93 public static final String HTMLPublicId = "-//W3C//DTD HTML 4.0//EN"; 94 95 98 public static final String HTMLSystemId = 99 "http://www.w3.org/TR/WD-html-in-xml/DTD/xhtml1-strict.dtd"; 100 101 104 public static final String XHTMLPublicId = 105 "-//W3C//DTD XHTML 1.0 Strict//EN"; 106 107 110 public static final String XHTMLSystemId = 111 "http://www.w3.org/TR/WD-html-in-xml/DTD/xhtml1-strict.dtd"; 112 116 private static Hashtable _byChar; 117 118 119 123 private static Hashtable _byName; 124 125 126 private static Hashtable _boolAttrs; 127 128 129 132 private static Hashtable _elemDefs; 133 134 135 139 private static final String ENTITIES_RESOURCE = "HTMLEntities.res"; 140 141 142 145 private static final int ONLY_OPENING = 0x0001; 146 147 150 private static final int ELEM_CONTENT = 0x0002; 151 152 153 156 private static final int PRESERVE = 0x0004; 157 158 159 162 private static final int OPT_CLOSING = 0x0008; 163 164 165 168 private static final int EMPTY = 0x0010 | ONLY_OPENING; 169 170 171 174 private static final int ALLOWED_HEAD = 0x0020; 175 176 177 180 private static final int CLOSE_P = 0x0040; 181 182 183 186 private static final int CLOSE_DD_DT = 0x0080; 187 188 189 192 private static final int CLOSE_SELF = 0x0100; 193 194 195 198 private static final int CLOSE_TABLE = 0x0200; 199 200 201 204 private static final int CLOSE_TH_TD = 0x04000; 205 206 207 214 public static boolean isEmptyTag( String tagName ) 215 { 216 return isElement( tagName, EMPTY ); 217 } 218 219 220 228 public static boolean isElementContent( String tagName ) 229 { 230 return isElement( tagName, ELEM_CONTENT ); 231 } 232 233 234 242 public static boolean isPreserveSpace( String tagName ) 243 { 244 return isElement( tagName, PRESERVE ); 245 } 246 247 248 256 public static boolean isOptionalClosing( String tagName ) 257 { 258 return isElement( tagName, OPT_CLOSING ); 259 } 260 261 262 269 public static boolean isOnlyOpening( String tagName ) 270 { 271 return isElement( tagName, ONLY_OPENING ); 272 } 273 274 275 285 public static boolean isClosing( String tagName, String openTag ) 286 { 287 if ( openTag.equalsIgnoreCase( "HEAD" ) ) 289 return ! isElement( tagName, ALLOWED_HEAD ); 290 if ( openTag.equalsIgnoreCase( "P" ) ) 292 return isElement( tagName, CLOSE_P ); 293 if ( openTag.equalsIgnoreCase( "DT" ) || openTag.equalsIgnoreCase( "DD" ) ) 295 return isElement( tagName, CLOSE_DD_DT ); 296 if ( openTag.equalsIgnoreCase( "LI" ) || openTag.equalsIgnoreCase( "OPTION" ) ) 298 return isElement( tagName, CLOSE_SELF ); 299 if ( openTag.equalsIgnoreCase( "THEAD" ) || openTag.equalsIgnoreCase( "TFOOT" ) || 301 openTag.equalsIgnoreCase( "TBODY" ) || openTag.equalsIgnoreCase( "TR" ) || 302 openTag.equalsIgnoreCase( "COLGROUP" ) ) 303 return isElement( tagName, CLOSE_TABLE ); 304 if ( openTag.equalsIgnoreCase( "TH" ) || openTag.equalsIgnoreCase( "TD" ) ) 306 return isElement( tagName, CLOSE_TH_TD ); 307 return false; 308 } 309 310 311 319 public static boolean isURI( String tagName, String attrName ) 320 { 321 return ( attrName.equalsIgnoreCase( "href" ) || attrName.equalsIgnoreCase( "src" ) ); 323 } 324 325 326 334 public static boolean isBoolean( String tagName, String attrName ) 335 { 336 String [] attrNames; 337 338 attrNames = (String []) _boolAttrs.get( tagName.toUpperCase() ); 339 if ( attrNames == null ) 340 return false; 341 for ( int i = 0 ; i < attrNames.length ; ++i ) 342 if ( attrNames[ i ].equalsIgnoreCase( attrName ) ) 343 return true; 344 return false; 345 } 346 347 348 356 public static int charFromName( String name ) 357 { 358 Object value; 359 360 initialize(); 361 value = _byName.get( name ); 362 if ( value != null && value instanceof Integer ) 363 return ( (Integer ) value ).intValue(); 364 else 365 return -1; 366 } 367 368 369 377 public static String fromChar(int value ) 378 { 379 if (value > 0xffff) 380 return null; 381 382 String name; 383 384 initialize(); 385 name = (String ) _byChar.get( new Integer ( value ) ); 386 return name; 387 } 388 389 390 396 private static void initialize() 397 { 398 InputStream is = null; 399 BufferedReader reader = null; 400 int index; 401 String name; 402 String value; 403 int code; 404 String line; 405 406 if ( _byName != null ) 408 return; 409 try { 410 _byName = new Hashtable (); 411 _byChar = new Hashtable (); 412 is = HTMLdtd.class.getResourceAsStream( ENTITIES_RESOURCE ); 413 if ( is == null ) 414 throw new RuntimeException ( "SER003 The resource [" + ENTITIES_RESOURCE + "] could not be found.\n" + ENTITIES_RESOURCE); 415 reader = new BufferedReader ( new InputStreamReader ( is ) ); 416 line = reader.readLine(); 417 while ( line != null ) { 418 if ( line.length() == 0 || line.charAt( 0 ) == '#' ) { 419 line = reader.readLine(); 420 continue; 421 } 422 index = line.indexOf( ' ' ); 423 if ( index > 1 ) { 424 name = line.substring( 0, index ); 425 ++index; 426 if ( index < line.length() ) { 427 value = line.substring( index ); 428 index = value.indexOf( ' ' ); 429 if ( index > 0 ) 430 value = value.substring( 0, index ); 431 code = Integer.parseInt( value ); 432 defineEntity( name, (char) code ); 433 } 434 } 435 line = reader.readLine(); 436 } 437 is.close(); 438 } catch ( Exception except ) { 439 throw new RuntimeException ( "SER003 The resource [" + ENTITIES_RESOURCE + "] could not load: " + 440 except.toString() + "\n" + ENTITIES_RESOURCE + "\t" + except.toString()); 441 } finally { 442 if ( is != null ) { 443 try { 444 is.close(); 445 } catch ( Exception except ) { } 446 } 447 } 448 } 449 450 451 463 private static void defineEntity( String name, char value ) 464 { 465 if ( _byName.get( name ) == null ) { 466 _byName.put( name, new Integer ( value ) ); 467 _byChar.put( new Integer ( value ), name ); 468 } 469 } 470 471 472 private static void defineElement( String name, int flags ) 473 { 474 _elemDefs.put( name, new Integer ( flags ) ); 475 } 476 477 478 private static void defineBoolean( String tagName, String attrName ) 479 { 480 defineBoolean( tagName, new String [] { attrName } ); 481 } 482 483 484 private static void defineBoolean( String tagName, String [] attrNames ) 485 { 486 _boolAttrs.put( tagName, attrNames ); 487 } 488 489 490 private static boolean isElement( String name, int flag ) 491 { 492 Integer flags; 493 494 flags = (Integer ) _elemDefs.get( name.toUpperCase() ); 495 if ( flags == null ) 496 return false; 497 else 498 return ( ( flags.intValue() & flag ) == flag ); 499 } 500 501 502 static 503 { 504 _elemDefs = new Hashtable (); 505 defineElement( "ADDRESS", CLOSE_P ); 506 defineElement( "AREA", EMPTY ); 507 defineElement( "BASE", EMPTY | ALLOWED_HEAD ); 508 defineElement( "BASEFONT", EMPTY ); 509 defineElement( "BLOCKQUOTE", CLOSE_P ); 510 defineElement( "BODY", OPT_CLOSING ); 511 defineElement( "BR", EMPTY ); 512 defineElement( "COL", EMPTY ); 513 defineElement( "COLGROUP", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE ); 514 defineElement( "DD", OPT_CLOSING | ONLY_OPENING | CLOSE_DD_DT ); 515 defineElement( "DIV", CLOSE_P ); 516 defineElement( "DL", ELEM_CONTENT | CLOSE_P ); 517 defineElement( "DT", OPT_CLOSING | ONLY_OPENING | CLOSE_DD_DT ); 518 defineElement( "FIELDSET", CLOSE_P ); 519 defineElement( "FORM", CLOSE_P ); 520 defineElement( "FRAME", EMPTY | OPT_CLOSING ); 521 defineElement( "H1", CLOSE_P ); 522 defineElement( "H2", CLOSE_P ); 523 defineElement( "H3", CLOSE_P ); 524 defineElement( "H4", CLOSE_P ); 525 defineElement( "H5", CLOSE_P ); 526 defineElement( "H6", CLOSE_P ); 527 defineElement( "HEAD", ELEM_CONTENT | OPT_CLOSING ); 528 defineElement( "HR", EMPTY | CLOSE_P ); 529 defineElement( "HTML", ELEM_CONTENT | OPT_CLOSING ); 530 defineElement( "IMG", EMPTY ); 531 defineElement( "INPUT", EMPTY ); 532 defineElement( "ISINDEX", EMPTY | ALLOWED_HEAD ); 533 defineElement( "LI", OPT_CLOSING | ONLY_OPENING | CLOSE_SELF ); 534 defineElement( "LINK", EMPTY | ALLOWED_HEAD ); 535 defineElement( "MAP", ALLOWED_HEAD ); 536 defineElement( "META", EMPTY | ALLOWED_HEAD ); 537 defineElement( "OL", ELEM_CONTENT | CLOSE_P ); 538 defineElement( "OPTGROUP", ELEM_CONTENT ); 539 defineElement( "OPTION", OPT_CLOSING | ONLY_OPENING | CLOSE_SELF ); 540 defineElement( "P", OPT_CLOSING | CLOSE_P | CLOSE_SELF ); 541 defineElement( "PARAM", EMPTY ); 542 defineElement( "PRE", PRESERVE | CLOSE_P ); 543 defineElement( "SCRIPT", ALLOWED_HEAD | PRESERVE ); 544 defineElement( "NOSCRIPT", ALLOWED_HEAD | PRESERVE ); 545 defineElement( "SELECT", ELEM_CONTENT ); 546 defineElement( "STYLE", ALLOWED_HEAD | PRESERVE ); 547 defineElement( "TABLE", ELEM_CONTENT | CLOSE_P ); 548 defineElement( "TBODY", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE ); 549 defineElement( "TD", OPT_CLOSING | CLOSE_TH_TD ); 550 defineElement( "TEXTAREA", PRESERVE ); 551 defineElement( "TFOOT", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE ); 552 defineElement( "TH", OPT_CLOSING | CLOSE_TH_TD ); 553 defineElement( "THEAD", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE ); 554 defineElement( "TITLE", ALLOWED_HEAD ); 555 defineElement( "TR", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE ); 556 defineElement( "UL", ELEM_CONTENT | CLOSE_P ); 557 558 _boolAttrs = new Hashtable (); 559 defineBoolean( "AREA", "href" ); 560 defineBoolean( "BUTTON", "disabled" ); 561 defineBoolean( "DIR", "compact" ); 562 defineBoolean( "DL", "compact" ); 563 defineBoolean( "FRAME", "noresize" ); 564 defineBoolean( "HR", "noshade" ); 565 defineBoolean( "IMAGE", "ismap" ); 566 defineBoolean( "INPUT", new String [] { "defaultchecked", "checked", "readonly", "disabled" } ); 567 defineBoolean( "LINK", "link" ); 568 defineBoolean( "MENU", "compact" ); 569 defineBoolean( "OBJECT", "declare" ); 570 defineBoolean( "OL", "compact" ); 571 defineBoolean( "OPTGROUP", "disabled" ); 572 defineBoolean( "OPTION", new String [] { "default-selected", "selected", "disabled" } ); 573 defineBoolean( "SCRIPT", "defer" ); 574 defineBoolean( "SELECT", new String [] { "multiple", "disabled" } ); 575 defineBoolean( "STYLE", "disabled" ); 576 defineBoolean( "TD", "nowrap" ); 577 defineBoolean( "TH", "nowrap" ); 578 defineBoolean( "TEXTAREA", new String [] { "disabled", "readonly" } ); 579 defineBoolean( "UL", "compact" ); 580 581 initialize(); 582 } 583 584 585 586 } 587 588 | Popular Tags |