1 16 17 18 22 23 package org.apache.xml.serialize; 24 25 import org.apache.xerces.dom.DOMMessageFormatter; 26 27 import java.io.InputStream ; 28 import java.io.InputStreamReader ; 29 import java.io.BufferedReader ; 30 import java.util.Hashtable ; 31 import java.util.Locale ; 32 33 34 48 public final class HTMLdtd 49 { 50 51 54 public static final String HTMLPublicId = "-//W3C//DTD HTML 4.01//EN"; 55 56 59 public static final String HTMLSystemId = 60 "http://www.w3.org/TR/html4/strict.dtd"; 61 62 65 public static final String XHTMLPublicId = 66 "-//W3C//DTD XHTML 1.0 Strict//EN"; 67 68 71 public static final String XHTMLSystemId = 72 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"; 73 74 78 private static Hashtable _byChar; 79 80 81 85 private static Hashtable _byName; 86 87 88 private static Hashtable _boolAttrs; 89 90 91 94 private static Hashtable _elemDefs; 95 96 97 101 private static final String ENTITIES_RESOURCE = "HTMLEntities.res"; 102 103 104 107 private static final int ONLY_OPENING = 0x0001; 108 109 112 private static final int ELEM_CONTENT = 0x0002; 113 114 115 118 private static final int PRESERVE = 0x0004; 119 120 121 124 private static final int OPT_CLOSING = 0x0008; 125 126 127 130 private static final int EMPTY = 0x0010 | ONLY_OPENING; 131 132 133 136 private static final int ALLOWED_HEAD = 0x0020; 137 138 139 142 private static final int CLOSE_P = 0x0040; 143 144 145 148 private static final int CLOSE_DD_DT = 0x0080; 149 150 151 154 private static final int CLOSE_SELF = 0x0100; 155 156 157 160 private static final int CLOSE_TABLE = 0x0200; 161 162 163 166 private static final int CLOSE_TH_TD = 0x04000; 167 168 169 176 public static boolean isEmptyTag( String tagName ) 177 { 178 return isElement( tagName, EMPTY ); 179 } 180 181 182 190 public static boolean isElementContent( String tagName ) 191 { 192 return isElement( tagName, ELEM_CONTENT ); 193 } 194 195 196 204 public static boolean isPreserveSpace( String tagName ) 205 { 206 return isElement( tagName, PRESERVE ); 207 } 208 209 210 218 public static boolean isOptionalClosing( String tagName ) 219 { 220 return isElement( tagName, OPT_CLOSING ); 221 } 222 223 224 231 public static boolean isOnlyOpening( String tagName ) 232 { 233 return isElement( tagName, ONLY_OPENING ); 234 } 235 236 237 247 public static boolean isClosing( String tagName, String openTag ) 248 { 249 if ( openTag.equalsIgnoreCase( "HEAD" ) ) 251 return ! isElement( tagName, ALLOWED_HEAD ); 252 if ( openTag.equalsIgnoreCase( "P" ) ) 254 return isElement( tagName, CLOSE_P ); 255 if ( openTag.equalsIgnoreCase( "DT" ) || openTag.equalsIgnoreCase( "DD" ) ) 257 return isElement( tagName, CLOSE_DD_DT ); 258 if ( openTag.equalsIgnoreCase( "LI" ) || openTag.equalsIgnoreCase( "OPTION" ) ) 260 return isElement( tagName, CLOSE_SELF ); 261 if ( openTag.equalsIgnoreCase( "THEAD" ) || openTag.equalsIgnoreCase( "TFOOT" ) || 263 openTag.equalsIgnoreCase( "TBODY" ) || openTag.equalsIgnoreCase( "TR" ) || 264 openTag.equalsIgnoreCase( "COLGROUP" ) ) 265 return isElement( tagName, CLOSE_TABLE ); 266 if ( openTag.equalsIgnoreCase( "TH" ) || openTag.equalsIgnoreCase( "TD" ) ) 268 return isElement( tagName, CLOSE_TH_TD ); 269 return false; 270 } 271 272 273 281 public static boolean isURI( String tagName, String attrName ) 282 { 283 return ( attrName.equalsIgnoreCase( "href" ) || attrName.equalsIgnoreCase( "src" ) ); 285 } 286 287 288 296 public static boolean isBoolean( String tagName, String attrName ) 297 { 298 String [] attrNames; 299 300 attrNames = (String []) _boolAttrs.get( tagName.toUpperCase(Locale.ENGLISH) ); 301 if ( attrNames == null ) 302 return false; 303 for ( int i = 0 ; i < attrNames.length ; ++i ) 304 if ( attrNames[ i ].equalsIgnoreCase( attrName ) ) 305 return true; 306 return false; 307 } 308 309 310 318 public static int charFromName( String name ) 319 { 320 Object value; 321 322 initialize(); 323 value = _byName.get( name ); 324 if ( value != null && value instanceof Integer ) 325 return ( (Integer ) value ).intValue(); 326 else 327 return -1; 328 } 329 330 331 339 public static String fromChar(int value ) 340 { 341 if (value > 0xffff) 342 return null; 343 344 String name; 345 346 initialize(); 347 name = (String ) _byChar.get( new Integer ( value ) ); 348 return name; 349 } 350 351 352 358 private static void initialize() 359 { 360 InputStream is = null; 361 BufferedReader reader = null; 362 int index; 363 String name; 364 String value; 365 int code; 366 String line; 367 368 if ( _byName != null ) 370 return; 371 try { 372 _byName = new Hashtable (); 373 _byChar = new Hashtable (); 374 is = HTMLdtd.class.getResourceAsStream( ENTITIES_RESOURCE ); 375 if ( is == null ) { 376 throw new RuntimeException ( 377 DOMMessageFormatter.formatMessage( 378 DOMMessageFormatter.SERIALIZER_DOMAIN, 379 "ResourceNotFound", new Object [] {ENTITIES_RESOURCE})); 380 } 381 reader = new BufferedReader ( new InputStreamReader ( is, "ASCII" ) ); 382 line = reader.readLine(); 383 while ( line != null ) { 384 if ( line.length() == 0 || line.charAt( 0 ) == '#' ) { 385 line = reader.readLine(); 386 continue; 387 } 388 index = line.indexOf( ' ' ); 389 if ( index > 1 ) { 390 name = line.substring( 0, index ); 391 ++index; 392 if ( index < line.length() ) { 393 value = line.substring( index ); 394 index = value.indexOf( ' ' ); 395 if ( index > 0 ) 396 value = value.substring( 0, index ); 397 code = Integer.parseInt( value ); 398 defineEntity( name, (char) code ); 399 } 400 } 401 line = reader.readLine(); 402 } 403 is.close(); 404 } catch ( Exception except ) { 405 throw new RuntimeException ( 406 DOMMessageFormatter.formatMessage( 407 DOMMessageFormatter.SERIALIZER_DOMAIN, 408 "ResourceNotLoaded", new Object [] {ENTITIES_RESOURCE, except.toString()})); 409 } finally { 410 if ( is != null ) { 411 try { 412 is.close(); 413 } catch ( Exception except ) { } 414 } 415 } 416 } 417 418 419 431 private static void defineEntity( String name, char value ) 432 { 433 if ( _byName.get( name ) == null ) { 434 _byName.put( name, new Integer ( value ) ); 435 _byChar.put( new Integer ( value ), name ); 436 } 437 } 438 439 440 private static void defineElement( String name, int flags ) 441 { 442 _elemDefs.put( name, new Integer ( flags ) ); 443 } 444 445 446 private static void defineBoolean( String tagName, String attrName ) 447 { 448 defineBoolean( tagName, new String [] { attrName } ); 449 } 450 451 452 private static void defineBoolean( String tagName, String [] attrNames ) 453 { 454 _boolAttrs.put( tagName, attrNames ); 455 } 456 457 458 private static boolean isElement( String name, int flag ) 459 { 460 Integer flags; 461 462 flags = (Integer ) _elemDefs.get( name.toUpperCase(Locale.ENGLISH) ); 463 if ( flags == null ) 464 return false; 465 else 466 return ( ( flags.intValue() & flag ) == flag ); 467 } 468 469 470 static 471 { 472 _elemDefs = new Hashtable (); 473 defineElement( "ADDRESS", CLOSE_P ); 474 defineElement( "AREA", EMPTY ); 475 defineElement( "BASE", EMPTY | ALLOWED_HEAD ); 476 defineElement( "BASEFONT", EMPTY ); 477 defineElement( "BLOCKQUOTE", CLOSE_P ); 478 defineElement( "BODY", OPT_CLOSING ); 479 defineElement( "BR", EMPTY ); 480 defineElement( "COL", EMPTY ); 481 defineElement( "COLGROUP", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE ); 482 defineElement( "DD", OPT_CLOSING | ONLY_OPENING | CLOSE_DD_DT ); 483 defineElement( "DIV", CLOSE_P ); 484 defineElement( "DL", ELEM_CONTENT | CLOSE_P ); 485 defineElement( "DT", OPT_CLOSING | ONLY_OPENING | CLOSE_DD_DT ); 486 defineElement( "FIELDSET", CLOSE_P ); 487 defineElement( "FORM", CLOSE_P ); 488 defineElement( "FRAME", EMPTY | OPT_CLOSING ); 489 defineElement( "H1", CLOSE_P ); 490 defineElement( "H2", CLOSE_P ); 491 defineElement( "H3", CLOSE_P ); 492 defineElement( "H4", CLOSE_P ); 493 defineElement( "H5", CLOSE_P ); 494 defineElement( "H6", CLOSE_P ); 495 defineElement( "HEAD", ELEM_CONTENT | OPT_CLOSING ); 496 defineElement( "HR", EMPTY | CLOSE_P ); 497 defineElement( "HTML", ELEM_CONTENT | OPT_CLOSING ); 498 defineElement( "IMG", EMPTY ); 499 defineElement( "INPUT", EMPTY ); 500 defineElement( "ISINDEX", EMPTY | ALLOWED_HEAD ); 501 defineElement( "LI", OPT_CLOSING | ONLY_OPENING | CLOSE_SELF ); 502 defineElement( "LINK", EMPTY | ALLOWED_HEAD ); 503 defineElement( "MAP", ALLOWED_HEAD ); 504 defineElement( "META", EMPTY | ALLOWED_HEAD ); 505 defineElement( "OL", ELEM_CONTENT | CLOSE_P ); 506 defineElement( "OPTGROUP", ELEM_CONTENT ); 507 defineElement( "OPTION", OPT_CLOSING | ONLY_OPENING | CLOSE_SELF ); 508 defineElement( "P", OPT_CLOSING | CLOSE_P | CLOSE_SELF ); 509 defineElement( "PARAM", EMPTY ); 510 defineElement( "PRE", PRESERVE | CLOSE_P ); 511 defineElement( "SCRIPT", ALLOWED_HEAD | PRESERVE ); 512 defineElement( "NOSCRIPT", ALLOWED_HEAD | PRESERVE ); 513 defineElement( "SELECT", ELEM_CONTENT ); 514 defineElement( "STYLE", ALLOWED_HEAD | PRESERVE ); 515 defineElement( "TABLE", ELEM_CONTENT | CLOSE_P ); 516 defineElement( "TBODY", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE ); 517 defineElement( "TD", OPT_CLOSING | CLOSE_TH_TD ); 518 defineElement( "TEXTAREA", PRESERVE ); 519 defineElement( "TFOOT", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE ); 520 defineElement( "TH", OPT_CLOSING | CLOSE_TH_TD ); 521 defineElement( "THEAD", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE ); 522 defineElement( "TITLE", ALLOWED_HEAD ); 523 defineElement( "TR", ELEM_CONTENT | OPT_CLOSING | CLOSE_TABLE ); 524 defineElement( "UL", ELEM_CONTENT | CLOSE_P ); 525 526 _boolAttrs = new Hashtable (); 527 defineBoolean( "AREA", "href" ); 528 defineBoolean( "BUTTON", "disabled" ); 529 defineBoolean( "DIR", "compact" ); 530 defineBoolean( "DL", "compact" ); 531 defineBoolean( "FRAME", "noresize" ); 532 defineBoolean( "HR", "noshade" ); 533 defineBoolean( "IMAGE", "ismap" ); 534 defineBoolean( "INPUT", new String [] { "defaultchecked", "checked", "readonly", "disabled" } ); 535 defineBoolean( "LINK", "link" ); 536 defineBoolean( "MENU", "compact" ); 537 defineBoolean( "OBJECT", "declare" ); 538 defineBoolean( "OL", "compact" ); 539 defineBoolean( "OPTGROUP", "disabled" ); 540 defineBoolean( "OPTION", new String [] { "default-selected", "selected", "disabled" } ); 541 defineBoolean( "SCRIPT", "defer" ); 542 defineBoolean( "SELECT", new String [] { "multiple", "disabled" } ); 543 defineBoolean( "STYLE", "disabled" ); 544 defineBoolean( "TD", "nowrap" ); 545 defineBoolean( "TH", "nowrap" ); 546 defineBoolean( "TEXTAREA", new String [] { "disabled", "readonly" } ); 547 defineBoolean( "UL", "compact" ); 548 549 initialize(); 550 } 551 552 553 554 } 555 556 | Popular Tags |