|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.xml.catalog.impl; import java.awt.*; import java.io.*; import java.beans.*; import java.util.*; import org.xml.sax.*; import org.xml.sax.helpers.*; import org.openide.util.*; import org.openide.xml.XMLUtil; import org.netbeans.modules.xml.catalog.spi.*; import org.netbeans.modules.xml.catalog.lib.*; /** * This catalog supports the XCatalog 0.2 and XML Catalog 0.4 proposal as * described at * draft. * * @author Petr Kuzel */ public final class XCatalog extends AbstractCatalog implements CatalogReader, CatalogDescriptor, Serializable, EntityResolver { /** Serial Version UID MUST NOT change. */ private static final long serialVersionUID = 06022001L; // ~~~~~~~~~~~~~~~ 0.4 grammar ~~~~~~~~~~~~~~~~~~ public static final String DTD_PUBLIC_ID_4 = "-//DTD XMLCatalog//EN"; // NOI18N /** XCatalog DTD resource name ("xcatalog.dtd"). */ static final String DTD = "xcatalog.dtd"; // NOI18N // tag and attribute names /** PublicID attribute name ("PublicID"). */ static final String PUBLICID_ATT_4 = "PublicId"; // NOI18N /** SystemID attribute name ("SystemID"). */ static final String SYSTEMID_ATT_4 = "SystemID"; // NOI18N // ~~~~~~~~~~~~~~~~~~~~ 0.2 grammar ~~~~~~~~~~~~~~~~~~~ public static final String DTD_PUBLIC_ID_2 = "-//DTD XCatalog//EN"; // NOI18N /** XCatalog element name ("XCatalog"). */ static final String XCATALOG_2 = "XMLCatalog"; // NOI18N /** XML Catalog version */ static final String VERSION_2 = "Version"; // NOI18N /** PublicID attribute name ("PublicID"). */ static final String PUBLICID_ATT_2 = "PublicID"; // NOI18N /** SystemID attribute name ("SystemID"). */ static final String SYSTEMID_ATT_2 = "SystemID"; // NOI18N // ~~~~~~~~~~~~~~~~~~~ 0.X grammar ~~~~~~~~~~~~~~~~~~~~` static final String MAP = "Map"; // NOI18N static final String EXTEND = "Extend"; // NOI18N static final String BASE = "Base"; // NOI18N static final String DELEGATE = "Delegate"; // NOI18N static final String REMAP = "Remap"; // NOI18N static final String HREF_ATT = "HRef"; // NOI18N /** * @serial Only catalog location is serialized. */ private String catalogSrc = null; private transient String shortDescription; private transient Image icon; // INIT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * Constructs an XCatalog instance. */ public XCatalog() { } /** * Deserialization constructor. */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); loadCatalog(catalogSrc); //!!! loading catalog during deserialization. Could be deferred } // Catalog loading (and error handling) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * Load catalog from given URL. */ public void loadCatalog(String systemID) { try { clearAll(); if (systemID == null) return; //balk it new CatalogParser(new InputSource(systemID)); updateShortDescription(catalogSrc); updateIcon(getDefaultIcon(0)); //!!! icon type should be deffered } catch (SAXException ex) { handleLoadError(ex); } catch (IOException ex) { handleLoadError(ex); } finally { notifyInvalidate(); } } private void handleLoadError(Exception ex) { updateShortDescription(ex.getLocalizedMessage()); updateIcon(getDefaultErrorIcon(0)); //!!! if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug("Can not read: " + shortDescription); // NOI18N } /** Update and fire. */ private void updateShortDescription(String loc) { String old = shortDescription; shortDescription = loc; firePropertyChange(PROP_CATALOG_DESC, old, shortDescription); } /** Update and fire. */ private void updateIcon(Image newIcon) { Image old = icon; icon = newIcon; firePropertyChange(PROP_CATALOG_ICON, old, icon); } // Properties (serialized) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * Set catalog source (URL) to be used. If specified invalid source * then no catalog is loaded update short description and icon. * * @param source should be be URL pointing to valid XML Catalog file */ public void setSource(String source) { catalogSrc = source; loadCatalog(source); firePropertyChange(PROP_CATALOG_NAME, null, getDisplayName()); } /** * @return currently catalog location URL, the URL may be invalid */ public String getSource() { return catalogSrc; } // Catalog Reader Interface ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * Reload the catalog from its original location. */ public void refresh() { if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug("Refreshing catalog...impl..."); // NOI18N loadCatalog(getSource()); } // Catalog Descriptor Interface ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * Return display name of this reader (e.g. "XCatalog Reader" or "SOCAT Reader" */ public String getDisplayName() { String location = catalogSrc; if (location == null || "".equals(location.trim())) { return Util.THIS.getString("PROP_missing_location"); } else { return Util.THIS.getString("PROP_display_name", catalogSrc); } } public Image getIcon(int type) { return icon; } public String getShortDescription() { return shortDescription; } public String toString() { return super.toString() + ":" + catalogSrc; // NOI18N } /* We must behave like immutable key! public boolean equals(Object obj) { if (obj instanceof XCatalog) { XCatalog cat = (XCatalog) obj; if (catalogSrc == null) return false; return catalogSrc.equals(cat.catalogSrc); } return false; } public int hashCode() { return catalogSrc != null ? catalogSrc.hashCode() : 0; } */ // Entity resolver interface ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * Resolves external entities using this catalog. * @see org.xml.sax.EntityResolver#resolveEntity(String,String) */ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug("resolveEntity(\""+publicId+"\", \""+systemId+"\")"); // NOI18N // public identifier resolution if (publicId != null) { // direct public id mappings String value = getPublicMapping(publicId); if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug(" map: \""+publicId+"\" -> \""+value+"\""); // NOI18N if (value != null) { InputSource source = resolveEntity(null, value); if (source == null) { source = new InputSource(value); } source.setPublicId(publicId); return source; } // delegates Enumeration delegates = getDelegateCatalogKeys(); while (delegates.hasMoreElements()) { String key = (String)delegates.nextElement(); if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug(" delegate: \""+key+"\""); // NOI18N if (publicId.startsWith(key)) { AbstractCatalog catalog = getDelegateCatalog(key); InputSource source = catalog.resolveEntity(publicId, systemId); if (source != null) { return source; } } } } // system identifier resolution String value = getSystemMapping(systemId); if (value != null) { if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug(" remap: \""+systemId+"\" -> \""+value+"\""); // NOI18N InputSource source = new InputSource(value); source.setPublicId(publicId); return source; } // try extenders Iterator it = extenders.iterator(); while (it.hasNext()) { XCatalog cat = (XCatalog) it.next(); InputSource mytry = cat.resolveEntity(publicId, systemId); if (mytry != null) return mytry; } // use default behavior if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug(" returning null!"); // NOI18N return null; } // Catalog parsing classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * Parser for XML Catalog document instances. * SAX 2 is used only to avoid deprecation messages. */ private class CatalogParser extends DefaultHandler { /** Current base. */ private String base; /** Parses the specified input source. */ public CatalogParser(InputSource source) throws SAXException, IOException { XMLReader parser = XMLUtil.createXMLReader(true); // setup parser parser.setEntityResolver(new Resolver()); // overwrite system entity resolver parser.setContentHandler(this); parser.setErrorHandler(this); // set initial base and parse setBase(source.getSystemId()); parser.parse(source); } /** * Sets the base from the given system identifier. The base is * the same as the system identifier with the least significant * part (the filename) removed. */ private void setBase(String systemId) throws SAXException { // normalize system id if (systemId == null) { systemId = ""; // NOI18N } // cut off the least significant part int index = systemId.lastIndexOf('/'); if (index != -1) { systemId = systemId.substring(0, index + 1); } // save base base = systemId; } //~~~~~~~~~~~~~~~~~ XCATALOG ATTRIBUTES SCANNER ~~~~~~~~~~~~~~~~~~~~~ /** Stop parsing on fatal error. */ public void fatalError(SAXException ex) throws SAXException { throw ex; } /** Stop parsing on error*/ public void error(SAXException ex) throws SAXException { throw ex; } /** * The start of an element. Parse attributes. */ public void startElement(String ns, String local, String qName, Attributes attrList) throws SAXException { try { // |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.