1 19 package org.netbeans.modules.xml.catalog.impl; 20 21 import java.awt.*; 22 import java.io.*; 23 import java.beans.*; 24 import java.util.*; 25 26 import org.xml.sax.*; 27 import org.xml.sax.helpers.*; 28 29 import org.openide.util.*; 30 import org.openide.xml.XMLUtil; 31 32 import org.netbeans.modules.xml.catalog.spi.*; 33 import org.netbeans.modules.xml.catalog.lib.*; 34 35 42 public final class XCatalog extends AbstractCatalog 43 implements CatalogReader, CatalogDescriptor, Serializable, EntityResolver { 44 45 46 private static final long serialVersionUID = 06022001L; 47 48 49 public static final String DTD_PUBLIC_ID_4 = "-//DTD XMLCatalog//EN"; 52 53 static final String DTD = "xcatalog.dtd"; 55 57 58 static final String PUBLICID_ATT_4 = "PublicId"; 60 61 static final String SYSTEMID_ATT_4 = "SystemID"; 63 65 public static final String DTD_PUBLIC_ID_2 = "-//DTD XCatalog//EN"; 67 68 static final String XCATALOG_2 = "XMLCatalog"; 70 71 static final String VERSION_2 = "Version"; 73 74 75 static final String PUBLICID_ATT_2 = "PublicID"; 77 78 static final String SYSTEMID_ATT_2 = "SystemID"; 80 82 static final String MAP = "Map"; 84 static final String EXTEND = "Extend"; 86 static final String BASE = "Base"; 88 static final String DELEGATE = "Delegate"; 90 static final String REMAP = "Remap"; 92 static final String HREF_ATT = "HRef"; 94 95 98 private String catalogSrc = null; 99 100 private transient String shortDescription; 101 102 private transient Image icon; 103 104 105 107 108 111 public XCatalog() { 112 } 113 114 117 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 118 in.defaultReadObject(); 119 loadCatalog(catalogSrc); } 121 122 123 125 126 129 public void loadCatalog(String systemID) { 130 try { 131 132 clearAll(); 133 134 if (systemID == null) return; 136 new CatalogParser(new InputSource(systemID)); 137 138 updateShortDescription(catalogSrc); 139 updateIcon(getDefaultIcon(0)); 141 142 } catch (SAXException ex) { 143 handleLoadError(ex); 144 } catch (IOException ex) { 145 handleLoadError(ex); 146 } finally { 147 notifyInvalidate(); 148 } 149 } 150 151 152 private void handleLoadError(Exception ex) { 153 updateShortDescription(ex.getLocalizedMessage()); 154 updateIcon(getDefaultErrorIcon(0)); 156 if ( Util.THIS.isLoggable() ) Util.THIS.debug("Can not read: " + shortDescription); } 158 159 160 161 private void updateShortDescription(String loc) { 162 String old = shortDescription; 163 shortDescription = loc; 164 firePropertyChange(PROP_CATALOG_DESC, old, shortDescription); 165 } 166 167 168 private void updateIcon(Image newIcon) { 169 Image old = icon; 170 icon = newIcon; 171 firePropertyChange(PROP_CATALOG_ICON, old, icon); 172 } 173 174 176 182 public void setSource(String source) { 183 catalogSrc = source; 184 loadCatalog(source); 185 firePropertyChange(PROP_CATALOG_NAME, null, getDisplayName()); 186 } 187 188 191 public String getSource() { 192 return catalogSrc; 193 } 194 195 196 198 201 public void refresh() { 202 if ( Util.THIS.isLoggable() ) Util.THIS.debug("Refreshing catalog...impl..."); 204 loadCatalog(getSource()); 205 } 206 207 208 210 213 public String getDisplayName() { 214 String location = catalogSrc; 215 if (location == null || "".equals(location.trim())) { 216 return Util.THIS.getString("PROP_missing_location"); 217 } else { 218 return Util.THIS.getString("PROP_display_name", catalogSrc); 219 } 220 } 221 222 public Image getIcon(int type) { 223 return icon; 224 } 225 226 public String getShortDescription() { 227 return shortDescription; 228 } 229 230 231 public String toString() { 232 return super.toString() + ":" + catalogSrc; } 234 235 251 252 254 255 259 public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { 260 261 if ( Util.THIS.isLoggable() ) Util.THIS.debug("resolveEntity(\""+publicId+"\", \""+systemId+"\")"); 263 if (publicId != null) { 265 266 String value = getPublicMapping(publicId); 268 269 if ( Util.THIS.isLoggable() ) Util.THIS.debug(" map: \""+publicId+"\" -> \""+value+"\""); 271 if (value != null) { 272 InputSource source = resolveEntity(null, value); 273 if (source == null) { 274 source = new InputSource(value); 275 } 276 source.setPublicId(publicId); 277 return source; 278 } 279 280 Enumeration delegates = getDelegateCatalogKeys(); 282 while (delegates.hasMoreElements()) { 283 String key = (String )delegates.nextElement(); 284 285 if ( Util.THIS.isLoggable() ) Util.THIS.debug(" delegate: \""+key+"\""); 287 if (publicId.startsWith(key)) { 288 AbstractCatalog catalog = getDelegateCatalog(key); 289 InputSource source = catalog.resolveEntity(publicId, systemId); 290 if (source != null) { 291 return source; 292 } 293 } 294 } 295 } 296 297 String value = getSystemMapping(systemId); 299 if (value != null) { 300 if ( Util.THIS.isLoggable() ) Util.THIS.debug(" remap: \""+systemId+"\" -> \""+value+"\""); 302 InputSource source = new InputSource(value); 303 source.setPublicId(publicId); 304 return source; 305 } 306 307 308 Iterator it = extenders.iterator(); 310 while (it.hasNext()) { 311 XCatalog cat = (XCatalog) it.next(); 312 InputSource mytry = cat.resolveEntity(publicId, systemId); 313 if (mytry != null) return mytry; 314 } 315 316 if ( Util.THIS.isLoggable() ) Util.THIS.debug(" returning null!"); 319 return null; 320 321 } 322 323 324 325 327 331 private class CatalogParser extends DefaultHandler { 332 333 334 private String base; 335 336 337 public CatalogParser(InputSource source) throws SAXException, IOException { 338 339 XMLReader parser = XMLUtil.createXMLReader(true); 340 341 parser.setEntityResolver(new Resolver()); parser.setContentHandler(this); 344 parser.setErrorHandler(this); 345 346 setBase(source.getSystemId()); 348 parser.parse(source); 349 350 } 351 352 353 358 private void setBase(String systemId) throws SAXException { 359 360 if (systemId == null) { 362 systemId = ""; } 364 365 int index = systemId.lastIndexOf('/'); 367 if (index != -1) { 368 systemId = systemId.substring(0, index + 1); 369 } 370 371 base = systemId; 373 374 } 375 376 377 379 380 public void fatalError(SAXException ex) throws SAXException { 381 throw ex; 382 } 383 384 385 public void error(SAXException ex) throws SAXException { 386 throw ex; 387 } 388 389 392 public void startElement(String ns, String local, String qName, Attributes attrList) throws SAXException { 393 394 try { 395 396 406 if (qName.equals(MAP)) { 407 408 String publicId = attrList.getValue(PUBLICID_ATT_4); 410 if (publicId == null) publicId = attrList.getValue(PUBLICID_ATT_2); 411 412 String href = attrList.getValue(HREF_ATT); 413 414 if ( Util.THIS.isLoggable() ) Util.THIS.debug("MAP \""+publicId+"\" \""+href+"\""); 416 if (Categorizer.isURL(href) == false) { 418 href = base + href; } 420 if (publicId != null) 421 addPublicMapping(publicId, href); 422 423 } else if (qName.equals(DELEGATE)) { 424 425 String publicId = attrList.getValue(PUBLICID_ATT_4); 427 if (publicId == null) publicId = attrList.getValue(PUBLICID_ATT_2); 428 String href = attrList.getValue(HREF_ATT); 429 430 if ( Util.THIS.isLoggable() ) Util.THIS.debug("DELEGATE \""+publicId+"\" \""+href+"\""); 432 if (Categorizer.isURL(href) == false) { 434 href = base + href; 435 } 436 String systemId = href; 438 XCatalog catalog = new XCatalog(); 440 catalog.loadCatalog(systemId); 441 addDelegateCatalog(publicId, catalog); 442 443 } else if (qName.equals(EXTEND)) { 444 445 String href = attrList.getValue(HREF_ATT); 447 448 if ( Util.THIS.isLoggable() ) Util.THIS.debug("EXTEND \""+href+"\""); 450 if (Categorizer.isURL(href) == false) { 452 href = base + href; 453 } 454 String systemId = href; 456 XCatalog extender = new XCatalog(); 458 extender.loadCatalog(systemId); 459 extenders.add(extender); 460 461 } else if (qName.equals(BASE)) { 462 463 String href = attrList.getValue(HREF_ATT); 465 466 if (href != null) { 468 base = href; 469 } 470 if ( Util.THIS.isLoggable() ) Util.THIS.debug("BASE \""+href+"\" -> \""+base+"\""); 472 } else if (qName.equals(REMAP)) { 473 474 476 String systemId = attrList.getValue(SYSTEMID_ATT_4); 477 if (systemId == null) systemId=attrList.getValue(SYSTEMID_ATT_2); 478 479 String href = attrList.getValue(HREF_ATT); 480 481 if ( Util.THIS.isLoggable() ) Util.THIS.debug("REMAP \""+systemId+"\" \""+href+"\""); 483 if (Categorizer.isURL(href) == false) { 485 href = base + href; 486 } 487 addSystemMapping(systemId, href); 488 489 } 490 491 } catch (Exception e) { 492 throw new SAXException(e); 493 } 494 495 } 496 497 498 private class Resolver implements EntityResolver { 499 500 501 public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { 502 503 if (DTD_PUBLIC_ID_2.equals(publicId) || DTD_PUBLIC_ID_4.equals(publicId)) { 505 InputSource src = new InputSource(); 506 src.setPublicId(publicId); 507 InputStream is = new ByteArrayInputStream(new byte[0]); 508 src.setByteStream(is); 509 src.setCharacterStream(new InputStreamReader(is, "UTF8")); return src; 511 } 512 513 return null; 515 516 } 517 518 } 519 520 } 521 522 } 523 | Popular Tags |