1 57 58 package org.enhydra.apache.xerces.readers; 59 60 import java.io.IOException ; 61 import java.io.InputStream ; 62 import java.io.InputStreamReader ; 63 import java.util.Enumeration ; 64 import java.util.Hashtable ; 65 import java.util.Vector ; 66 67 import org.enhydra.apache.xerces.parsers.SAXParser; 68 import org.xml.sax.AttributeList ; 69 import org.xml.sax.DocumentHandler ; 70 import org.xml.sax.EntityResolver ; 71 import org.xml.sax.InputSource ; 72 import org.xml.sax.SAXException ; 73 74 133 public class XCatalog 134 extends XMLCatalogHandler 135 { 136 137 141 143 144 public static final String XCATALOG_DTD_PUBLICID = "-//DTD XCatalog//EN"; 145 146 148 149 static final String DTD = "xcatalog.dtd"; 150 151 152 static final String XCATALOG = "XCatalog"; 153 154 155 static final String MAP = "Map"; 156 157 158 static final String PUBLICID = "PublicID"; 159 160 161 static final String HREF = "HRef"; 162 163 164 static final String DELEGATE = "Delegate"; 165 166 167 static final String EXTEND = "Extend"; 168 169 170 static final String BASE = "Base"; 171 172 173 static final String REMAP = "Remap"; 174 175 176 static final String SYSTEMID = "SystemID"; 177 178 180 181 private static final boolean DEBUG = false; 182 183 187 188 private Hashtable delegate = new Hashtable (); 189 190 191 private Vector delegateOrder = new Vector (); 192 193 197 200 public XCatalog() { 201 } 202 203 207 216 public void loadCatalog(InputSource source) 217 throws SAXException , IOException 218 { 219 220 new Parser(source); 221 222 227 228 } 230 254 255 259 274 public InputSource resolveEntity(String publicId, String systemId) 275 throws SAXException , IOException 276 { 277 278 if (DEBUG) { 279 System.out.println("resolveEntity(\""+publicId+"\", \""+systemId+"\")"); 280 } 281 282 if (publicId != null) { 284 String value = getPublicMapping(publicId); 286 if (DEBUG) { 287 System.out.println(" map: \""+publicId+"\" -> \""+value+"\""); 288 } 289 if (value != null) { 290 InputSource source = resolveEntity(null, value); 291 if (source == null) { 292 source = new InputSource (value); 293 } 294 source.setPublicId(publicId); 295 return source; 296 } 297 298 Enumeration delegates = getDelegateCatalogKeys(); 300 while (delegates.hasMoreElements()) { 301 String key = (String )delegates.nextElement(); 302 if (DEBUG) { 303 System.out.println(" delegate: \""+key+"\""); 304 } 305 if (publicId.startsWith(key)) { 306 XMLCatalogHandler catalog = getDelegateCatalog(key); 307 InputSource source = catalog.resolveEntity(publicId, systemId); 308 if (source != null) { 309 return source; 310 } 311 } 312 } 313 } 314 315 String value = getSystemMapping(systemId); 317 if (value != null) { 318 if (DEBUG) { 319 System.out.println(" remap: \""+systemId+"\" -> \""+value+"\""); 320 } 321 InputSource source = new InputSource (value); 322 source.setPublicId(publicId); 323 return source; 324 } 325 326 if (DEBUG) { 328 System.out.println(" returning null!"); 329 } 330 return null; 331 332 } 334 338 350 public void addDelegateCatalog(String prefix, XCatalog catalog) { 351 352 synchronized (delegate) { 353 if (!delegate.containsKey(prefix)) { 355 int size = delegateOrder.size(); 356 boolean found = false; 357 for (int i = 0; i < size; i++) { 358 String element = (String )delegateOrder.elementAt(i); 359 if (prefix.startsWith(element) || prefix.compareTo(element) < 0) { 360 delegateOrder.insertElementAt(prefix, i); 361 found = true; 362 break; 363 } 364 } 365 if (!found) { 366 delegateOrder.addElement(prefix); 367 } 368 } 369 370 delegate.put(prefix, catalog); 372 } 373 374 } 376 381 public void removeDelegateCatalog(String prefix) { 382 383 synchronized (delegate) { 384 delegate.remove(prefix); 385 delegateOrder.removeElement(prefix); 386 } 387 388 } 390 391 public Enumeration getDelegateCatalogKeys() { 392 return delegateOrder.elements(); 393 } 394 395 396 public XCatalog getDelegateCatalog(String prefix) { 397 return (XCatalog)delegate.get(prefix); 398 } 399 400 404 405 boolean isURL(String str) { 406 try { 407 new java.net.URL (str); 408 return true; 409 } 410 catch (java.net.MalformedURLException e) { 411 } 413 return false; 414 } 415 416 420 421 class Parser 422 extends SAXParser 423 implements DocumentHandler 424 { 425 426 430 431 private String base; 432 433 437 438 public Parser(InputSource source) 439 throws SAXException , IOException 440 { 441 442 setEntityResolver(new Resolver ()); 444 setDocumentHandler((DocumentHandler )this); 445 446 setBase(source.getSystemId()); 448 parse(source); 449 450 } 452 456 461 protected void setBase(String systemId) throws SAXException { 462 463 if (systemId == null) { 465 systemId = ""; 466 } 467 468 systemId = fEntityHandler.expandSystemId(systemId); 470 471 int index = systemId.lastIndexOf('/'); 473 if (index != -1) { 474 systemId = systemId.substring(0, index + 1); 475 } 476 477 base = systemId; 479 480 } 482 486 487 public void processingInstruction(String target, String data) {} 488 489 490 public void setDocumentLocator(org.xml.sax.Locator locator) {} 491 492 493 public void startDocument() {} 494 495 496 public void endElement(String elementName) {} 497 498 499 public void endDocument() {} 500 501 502 public void characters(char ch[], int start, int length) {} 503 504 505 public void ignorableWhitespace(char ch[], int start, int length) {} 506 507 508 public void startElement(String elementName, AttributeList attrList) 509 throws SAXException 510 { 511 512 try { 513 if (elementName.equals(XCATALOG)) { 515 return; 516 } 517 518 if (elementName.equals(MAP)) { 520 String publicId = attrList.getValue(PUBLICID); 522 String href = attrList.getValue(HREF); 523 if (DEBUG) { 524 System.out.println("MAP \""+publicId+"\" \""+href+"\""); 525 } 526 527 if (!isURL(href)) { 529 href = base + href; 530 } 531 addPublicMapping(publicId, href); 532 } 533 534 else if (elementName.equals(DELEGATE)) { 536 String publicId = attrList.getValue(PUBLICID); 538 String href = attrList.getValue(HREF); 539 if (DEBUG) { 540 System.out.println("DELEGATE \""+publicId+"\" \""+href+"\""); 541 } 542 543 if (!isURL(href)) { 545 href = base + href; 546 } 547 String systemId = fEntityHandler.expandSystemId(href); 548 549 XCatalog catalog = new XCatalog(); 551 catalog.loadCatalog(new InputSource (systemId)); 552 addDelegateCatalog(publicId, catalog); 553 } 554 555 else if (elementName.equals(EXTEND)) { 557 String href = attrList.getValue(HREF); 559 if (DEBUG) { 560 System.out.println("EXTEND \""+href+"\""); 561 } 562 563 if (!isURL(href)) { 565 href = base + href; 566 } 567 String systemId = fEntityHandler.expandSystemId(href); 568 569 XCatalog.this.loadCatalog(new InputSource (systemId)); 571 } 572 573 else if (elementName.equals(BASE)) { 575 String href = attrList.getValue(HREF); 577 578 setBase(href); 580 if (DEBUG) { 581 System.out.println("BASE \""+href+"\" -> \""+base+"\""); 582 } 583 } 584 585 else if (elementName.equals(REMAP)) { 587 String systemId = attrList.getValue(SYSTEMID); 589 String href = attrList.getValue(HREF); 590 if (DEBUG) { 591 System.out.println("REMAP \""+systemId+"\" \""+href+"\""); 592 } 593 594 if (!isURL(href)) { 596 href = base + href; 597 } 598 addSystemMapping(systemId, href); 599 } 600 } 601 catch (Exception e) { 602 throw new SAXException (e); 603 } 604 605 } 607 611 612 class Resolver 613 implements EntityResolver 614 { 615 616 617 public InputSource resolveEntity(String publicId, String systemId) 618 throws SAXException , IOException 619 { 620 621 if (publicId != null && publicId.equals(XCATALOG_DTD_PUBLICID)) { 623 InputSource src = new InputSource (); 624 src.setPublicId(publicId); 625 InputStream is = getClass().getResourceAsStream(DTD); 626 if (is == null) { 627 throw new IOException ("Can't file xcatalog DTD on classpath: " + DTD); 628 } 629 src.setByteStream(is); 630 src.setCharacterStream(new InputStreamReader (is)); 631 return src; 632 } 633 634 return null; 636 637 } 639 } 641 } 643 } | Popular Tags |