1 16 19 package org.apache.xml.serializer; 20 21 import java.io.BufferedReader ; 22 import java.io.InputStream ; 23 import java.io.InputStreamReader ; 24 import java.io.UnsupportedEncodingException ; 25 import java.net.URL ; 26 import java.util.Hashtable ; 27 import java.util.PropertyResourceBundle ; 28 import java.util.Enumeration ; 29 import java.util.ResourceBundle ; 30 31 import javax.xml.transform.TransformerException ; 32 33 import org.apache.xml.res.XMLErrorResources; 34 import org.apache.xml.res.XMLMessages; 35 import org.apache.xml.utils.CharKey; 36 import org.apache.xml.utils.SystemIDResolver; 37 import org.apache.xml.utils.WrappedRuntimeException; 38 39 49 class CharInfo 50 { 51 52 private Hashtable m_charToEntityRef = new Hashtable (); 53 54 58 public static String HTML_ENTITIES_RESOURCE = "org.apache.xml.serializer.HTMLEntities"; 59 60 64 public static String XML_ENTITIES_RESOURCE = "org.apache.xml.serializer.XMLEntities"; 65 66 67 public static final char S_HORIZONAL_TAB = 0x09; 68 69 70 public static final char S_LINEFEED = 0x0A; 71 72 73 public static char S_CARRIAGERETURN = 0x0D; 74 75 80 final boolean onlyQuotAmpLtGt; 81 82 83 private static final int ASCII_MAX = 128; 84 85 88 private boolean[] isSpecialAttrASCII = new boolean[ASCII_MAX]; 89 90 93 private boolean[] isSpecialTextASCII = new boolean[ASCII_MAX]; 94 95 private boolean[] isCleanTextASCII = new boolean[ASCII_MAX]; 96 97 102 private int array_of_bits[] = createEmptySetOfIntegers(65535); 103 104 105 111 private static final int SHIFT_PER_WORD = 5; 112 113 122 private static final int LOW_ORDER_BITMASK = 0x1f; 123 124 129 private int firstWordNotUsed; 130 131 132 153 private CharInfo(String entitiesResource, String method) 154 { 155 this(entitiesResource, method, false); 156 } 157 158 private CharInfo(String entitiesResource, String method, boolean internal) 159 { 160 ResourceBundle entities = null; 161 boolean noExtraEntities = true; 162 163 171 if (internal) { 172 try { 173 entities = PropertyResourceBundle.getBundle(entitiesResource); 176 } catch (Exception e) {} 177 } 178 179 if (entities != null) { 180 Enumeration keys = entities.getKeys(); 181 while (keys.hasMoreElements()){ 182 String name = (String ) keys.nextElement(); 183 String value = entities.getString(name); 184 int code = Integer.parseInt(value); 185 defineEntity(name, (char) code); 186 if (extraEntity(code)) 187 noExtraEntities = false; 188 } 189 set(S_LINEFEED); 190 set(S_CARRIAGERETURN); 191 } else { 192 InputStream is = null; 193 194 try { 197 if (internal) { 198 is = CharInfo.class.getResourceAsStream(entitiesResource); 199 } else { 200 ClassLoader cl = ObjectFactory.findClassLoader(); 201 if (cl == null) { 202 is = ClassLoader.getSystemResourceAsStream(entitiesResource); 203 } else { 204 is = cl.getResourceAsStream(entitiesResource); 205 } 206 207 if (is == null) { 208 try { 209 URL url = new URL (entitiesResource); 210 is = url.openStream(); 211 } catch (Exception e) {} 212 } 213 } 214 215 if (is == null) { 216 throw new RuntimeException ( 217 XMLMessages.createXMLMessage( 218 XMLErrorResources.ER_RESOURCE_COULD_NOT_FIND, 219 new Object [] {entitiesResource, entitiesResource})); 220 } 221 222 241 BufferedReader reader; 242 try { 243 reader = new BufferedReader (new InputStreamReader (is, "UTF-8")); 244 } catch (UnsupportedEncodingException e) { 245 reader = new BufferedReader (new InputStreamReader (is)); 246 } 247 248 String line = reader.readLine(); 249 250 while (line != null) { 251 if (line.length() == 0 || line.charAt(0) == '#') { 252 line = reader.readLine(); 253 254 continue; 255 } 256 257 int index = line.indexOf(' '); 258 259 if (index > 1) { 260 String name = line.substring(0, index); 261 262 ++index; 263 264 if (index < line.length()) { 265 String value = line.substring(index); 266 index = value.indexOf(' '); 267 268 if (index > 0) { 269 value = value.substring(0, index); 270 } 271 272 int code = Integer.parseInt(value); 273 274 defineEntity(name, (char) code); 275 if (extraEntity(code)) 276 noExtraEntities = false; 277 } 278 } 279 280 line = reader.readLine(); 281 } 282 283 is.close(); 284 set(S_LINEFEED); 285 set(S_CARRIAGERETURN); 286 } catch (Exception e) { 287 throw new RuntimeException ( 288 XMLMessages.createXMLMessage( 289 XMLErrorResources.ER_RESOURCE_COULD_NOT_LOAD, 290 new Object [] { entitiesResource, 291 e.toString(), 292 entitiesResource, 293 e.toString()})); 294 } finally { 295 if (is != null) { 296 try { 297 is.close(); 298 } catch (Exception except) {} 299 } 300 } 301 } 302 303 308 for (int ch = 0; ch <ASCII_MAX; ch++) 309 if((((0x20 <= ch || (0x0A == ch || 0x0D == ch || 0x09 == ch))) 310 && (!get(ch))) || ('"' == ch)) 311 { 312 isCleanTextASCII[ch] = true; 313 isSpecialTextASCII[ch] = false; 314 } 315 else { 316 isCleanTextASCII[ch] = false; 317 isSpecialTextASCII[ch] = true; 318 } 319 320 329 if (Method.XML.equals(method)) 330 { 331 set(S_HORIZONAL_TAB); 332 } 333 334 335 onlyQuotAmpLtGt = noExtraEntities; 336 337 for (int i=0; i<ASCII_MAX; i++) 339 isSpecialAttrASCII[i] = get(i); 340 341 } 342 343 354 private void defineEntity(String name, char value) 355 { 356 CharKey character = new CharKey(value); 357 358 m_charToEntityRef.put(character, name); 359 set(value); 360 } 361 362 private CharKey m_charKey = new CharKey(); 363 364 380 synchronized public String getEntityNameForChar(char value) 381 { 382 m_charKey.setChar(value); 384 return (String ) m_charToEntityRef.get(m_charKey); 385 } 386 387 397 public final boolean isSpecialAttrChar(int value) 398 { 399 402 if (value < ASCII_MAX) 403 return isSpecialAttrASCII[value]; 404 405 return get(value); 408 } 409 410 420 public final boolean isSpecialTextChar(int value) 421 { 422 425 if (value < ASCII_MAX) 426 return isSpecialTextASCII[value]; 427 428 return get(value); 431 } 432 433 440 public final boolean isTextASCIIClean(int value) 441 { 442 return isCleanTextASCII[value]; 443 } 444 445 453 454 473 public static CharInfo getCharInfo(String entitiesFileName, String method) 474 { 475 CharInfo charInfo = (CharInfo) m_getCharInfoCache.get(entitiesFileName); 476 if (charInfo != null) { 477 return charInfo; 478 } 479 480 try { 482 charInfo = new CharInfo(entitiesFileName, method, true); 483 m_getCharInfoCache.put(entitiesFileName, charInfo); 484 return charInfo; 485 } catch (Exception e) {} 486 487 try { 489 return new CharInfo(entitiesFileName, method); 490 } catch (Exception e) {} 491 492 String absoluteEntitiesFileName; 493 494 if (entitiesFileName.indexOf(':') < 0) { 495 absoluteEntitiesFileName = 496 SystemIDResolver.getAbsoluteURIFromRelative(entitiesFileName); 497 } else { 498 try { 499 absoluteEntitiesFileName = 500 SystemIDResolver.getAbsoluteURI(entitiesFileName, null); 501 } catch (TransformerException te) { 502 throw new WrappedRuntimeException(te); 503 } 504 } 505 506 return new CharInfo(absoluteEntitiesFileName, method, false); 507 } 508 509 510 private static Hashtable m_getCharInfoCache = new Hashtable (); 511 512 518 private static int arrayIndex(int i) { 519 return (i >> SHIFT_PER_WORD); 520 } 521 522 527 private static int bit(int i) { 528 int ret = (1 << (i & LOW_ORDER_BITMASK)); 529 return ret; 530 } 531 532 536 private int[] createEmptySetOfIntegers(int max) { 537 firstWordNotUsed = 0; 539 int[] arr = new int[arrayIndex(max - 1) + 1]; 540 return arr; 541 542 } 543 544 550 private final void set(int i) { 551 int j = (i >> SHIFT_PER_WORD); int k = j + 1; 553 554 if(firstWordNotUsed < k) firstWordNotUsed = k; 556 557 array_of_bits[j] |= (1 << (i & LOW_ORDER_BITMASK)); 558 } 559 560 561 571 private final boolean get(int i) { 572 573 boolean in_the_set = false; 574 int j = (i >> SHIFT_PER_WORD); if(j < firstWordNotUsed) 578 in_the_set = (array_of_bits[j] & 579 (1 << (i & LOW_ORDER_BITMASK)) 580 ) != 0; return in_the_set; 582 } 583 584 591 private boolean extraEntity(int entityValue) 592 { 593 boolean extra = false; 594 if (entityValue < 128) 595 { 596 switch (entityValue) 597 { 598 case 34 : case 38 : case 60 : case 62 : break; 603 default : extra = true; 605 } 606 } 607 return extra; 608 } 609 } 610 | Popular Tags |