[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xerces-cvs
Subject:    svn commit: r1544645 [2/2] - /xerces/xml-commons/trunk/java/src/org/apache/xml/resolver/Catalog.java
From:       mrglavas () apache ! org
Date:       2013-11-22 19:11:43
Message-ID: 20131122191143.DF2072388AB8 () eris ! apache ! org
[Download RAW message or body]


Modified: xerces/xml-commons/trunk/java/src/org/apache/xml/resolver/Catalog.java
URL: http://svn.apache.org/viewvc/xerces/xml-commons/trunk/java/src/org/apache/xml/resolver/Catalog.java?rev=1544645&r1=1544644&r2=1544645&view=diff
 ==============================================================================
--- xerces/xml-commons/trunk/java/src/org/apache/xml/resolver/Catalog.java (original)
+++ xerces/xml-commons/trunk/java/src/org/apache/xml/resolver/Catalog.java Fri Nov 22 \
19:11:43 2013 @@ -189,2066 +189,2066 @@ import org.apache.xml.resolver.readers.T
  * Inc.</p>
  */
 public class Catalog {
-  /** The BASE Catalog Entry type. */
-  public static final int BASE     = CatalogEntry.addEntryType("BASE", 1);
+    /** The BASE Catalog Entry type. */
+    public static final int BASE     = CatalogEntry.addEntryType("BASE", 1);
 
-  /** The CATALOG Catalog Entry type. */
-  public static final int CATALOG  = CatalogEntry.addEntryType("CATALOG", 1);
+    /** The CATALOG Catalog Entry type. */
+    public static final int CATALOG  = CatalogEntry.addEntryType("CATALOG", 1);
 
-  /** The DOCUMENT Catalog Entry type. */
-  public static final int DOCUMENT = CatalogEntry.addEntryType("DOCUMENT", 1);
+    /** The DOCUMENT Catalog Entry type. */
+    public static final int DOCUMENT = CatalogEntry.addEntryType("DOCUMENT", 1);
 
-  /** The OVERRIDE Catalog Entry type. */
-  public static final int OVERRIDE = CatalogEntry.addEntryType("OVERRIDE", 1);
-
-  /** The SGMLDECL Catalog Entry type. */
-  public static final int SGMLDECL = CatalogEntry.addEntryType("SGMLDECL", 1);
-
-  /** The DELEGATE_PUBLIC Catalog Entry type. */
-  public static final int DELEGATE_PUBLIC = \
                CatalogEntry.addEntryType("DELEGATE_PUBLIC", 2);
-
-  /** The DELEGATE_SYSTEM Catalog Entry type. */
-  public static final int DELEGATE_SYSTEM = \
                CatalogEntry.addEntryType("DELEGATE_SYSTEM", 2);
-
-  /** The DELEGATE_URI Catalog Entry type. */
-  public static final int DELEGATE_URI = CatalogEntry.addEntryType("DELEGATE_URI", \
                2);
-
-  /** The DOCTYPE Catalog Entry type. */
-  public static final int DOCTYPE  = CatalogEntry.addEntryType("DOCTYPE", 2);
-
-  /** The DTDDECL Catalog Entry type. */
-  public static final int DTDDECL  = CatalogEntry.addEntryType("DTDDECL", 2);
-
-  /** The ENTITY Catalog Entry type. */
-  public static final int ENTITY   = CatalogEntry.addEntryType("ENTITY", 2);
-
-  /** The LINKTYPE Catalog Entry type. */
-  public static final int LINKTYPE = CatalogEntry.addEntryType("LINKTYPE", 2);
-
-  /** The NOTATION Catalog Entry type. */
-  public static final int NOTATION = CatalogEntry.addEntryType("NOTATION", 2);
-
-  /** The PUBLIC Catalog Entry type. */
-  public static final int PUBLIC   = CatalogEntry.addEntryType("PUBLIC", 2);
-
-  /** The SYSTEM Catalog Entry type. */
-  public static final int SYSTEM   = CatalogEntry.addEntryType("SYSTEM", 2);
-
-  /** The URI Catalog Entry type. */
-  public static final int URI      = CatalogEntry.addEntryType("URI", 2);
-
-  /** The REWRITE_SYSTEM Catalog Entry type. */
-  public static final int REWRITE_SYSTEM = \
                CatalogEntry.addEntryType("REWRITE_SYSTEM", 2);
-
-  /** The REWRITE_URI Catalog Entry type. */
-  public static final int REWRITE_URI = CatalogEntry.addEntryType("REWRITE_URI", 2);
-  /** The SYSTEM_SUFFIX Catalog Entry type. */
-  public static final int SYSTEM_SUFFIX = CatalogEntry.addEntryType("SYSTEM_SUFFIX", \
                2);
-  /** The URI_SUFFIX Catalog Entry type. */
-  public static final int URI_SUFFIX = CatalogEntry.addEntryType("URI_SUFFIX", 2);
-
-  /**
-   * The base URI for relative system identifiers in the catalog.
-   * This may be changed by BASE entries in the catalog.
-   */
-  protected URL base;
-
-  /** The base URI of the Catalog file currently being parsed. */
-  protected URL catalogCwd;
-
-  /** The catalog entries currently known to the system. */
-  protected Vector catalogEntries = new Vector();
-
-  /** The default initial override setting. */
-  protected boolean default_override = true;
-
-  /** The catalog manager in use for this instance. */
-  protected CatalogManager catalogManager = CatalogManager.getStaticManager();
-
-  /**
-   * A vector of catalog files to be loaded.
-   *
-   * <p>This list is initially established by
-   * <code>loadSystemCatalogs</code> when
-   * it parses the system catalog list, but CATALOG entries may
-   * contribute to it during the course of parsing.</p>
-   *
-   * @see #loadSystemCatalogs
-   * @see #localCatalogFiles
-   */
-  protected Vector catalogFiles = new Vector();
-
-  /**
-   * A vector of catalog files constructed during processing of
-   * CATALOG entries in the current catalog.
-   *
-   * <p>This two-level system is actually necessary to correctly implement
-   * the semantics of the CATALOG entry. If one catalog file includes
-   * another with a CATALOG entry, the included catalog logically
-   * occurs <i>at the end</i> of the including catalog, and after any
-   * preceding CATALOG entries. In other words, the CATALOG entry
-   * cannot insert anything into the middle of a catalog file.</p>
-   *
-   * <p>When processing reaches the end of each catalog files, any
-   * elements on this vector are added to the front of the
-   * <code>catalogFiles</code> vector.</p>
-   *
-   * @see #catalogFiles
-   */
-  protected Vector localCatalogFiles = new Vector();
-
-  /**
-   * A vector of Catalogs.
-   *
-   * <p>The semantics of Catalog resolution are such that each
-   * catalog is effectively a list of Catalogs (in other words,
-   * a recursive list of Catalog instances).</p>
-   *
-   * <p>Catalogs that are processed as the result of CATALOG or
-   * DELEGATE* entries are subordinate to the catalog that contained
-   * them, but they may in turn have subordinate catalogs.</p>
-   *
-   * <p>Catalogs are only loaded when they are needed, so this vector
-   * initially contains a list of Catalog filenames (URLs). If, during
-   * processing, one of these catalogs has to be loaded, the resulting
-   * Catalog object is placed in the vector, effectively caching it
-   * for the next query.</p>
-   */
-  protected Vector catalogs = new Vector();
-
-  /**
-   * A vector of DELEGATE* Catalog entries constructed during
-   * processing of the Catalog.
-   *
-   * <p>This two-level system has two purposes; first, it allows
-   * us to sort the DELEGATE* entries by the length of the partial
-   * public identifier so that a linear search encounters them in
-   * the correct order and second, it puts them all at the end of
-   * the Catalog.</p>
-   *
-   * <p>When processing reaches the end of each catalog file, any
-   * elements on this vector are added to the end of the
-   * <code>catalogEntries</code> vector. This assures that matching
-   * PUBLIC keywords are encountered before DELEGATE* entries.</p>
-   */
-  protected Vector localDelegate = new Vector();
-
-  /**
-   * A hash of CatalogReaders.
-   *
-   * <p>This hash maps MIME types to elements in the readerArr
-   * vector. This allows the Catalog to quickly locate the reader
-   * for a particular MIME type.</p>
-   */
-  protected Hashtable readerMap = new Hashtable();
-
-  /**
-   * A vector of CatalogReaders.
-   *
-   * <p>This vector contains all of the readers in the order that they
-   * were added. In the event that a catalog is read from a file, where
-   * the MIME type is unknown, each reader is attempted in turn until
-   * one succeeds.</p>
-   */
-  protected Vector readerArr = new Vector();
-
-  /**
-   * Constructs an empty Catalog.
-   *
-   * <p>The constructor interrogates the relevant system properties
-   * using the default (static) CatalogManager
-   * and initializes the catalog data structures.</p>
-   */
-  public Catalog() {
-    // nop;
-  }
-
-  /**
-   * Constructs an empty Catalog with a specific CatalogManager.
-   *
-   * <p>The constructor interrogates the relevant system properties
-   * using the specified Catalog Manager
-   * and initializes the catalog data structures.</p>
-   */
-  public Catalog(CatalogManager manager) {
-    catalogManager = manager;
-  }
-
-  /**
-   * Return the CatalogManager used by this catalog.
-   *
-   */
-  public CatalogManager getCatalogManager() {
-    return catalogManager;
-  }
-
-  /**
-   * Establish the CatalogManager used by this catalog.
-   *
-   */
-  public void setCatalogManager(CatalogManager manager) {
-    catalogManager = manager;
-  }
-
-  /**
-   * Setup readers.
-   */
-  public void setupReaders() {
-    SAXParserFactory spf = SAXParserFactory.newInstance();
-    spf.setNamespaceAware(true);
-    spf.setValidating(false);
-
-    SAXCatalogReader saxReader = new SAXCatalogReader(spf);
-
-    saxReader.setCatalogParser(null, "XCatalog",
-			       "org.apache.xml.resolver.readers.XCatalogReader");
-
-    saxReader.setCatalogParser(OASISXMLCatalogReader.namespaceName,
-			       "catalog",
-			       "org.apache.xml.resolver.readers.OASISXMLCatalogReader");
-
-    addReader("application/xml", saxReader);
-
-    TR9401CatalogReader textReader = new TR9401CatalogReader();
-    addReader("text/plain", textReader);
-  }
-
-  /**
-   * Add a new CatalogReader to the Catalog.
-   *
-   * <p>This method allows you to add a new CatalogReader to the
-   * catalog. The reader will be associated with the specified mimeType.
-   * You can only have one reader per mimeType.</p>
-   *
-   * <p>In the absence of a mimeType (e.g., when reading a catalog
-   * directly from a file on the local system), the readers are attempted
-   * in the order that you add them to the Catalog.</p>
-   *
-   * <p>Note that subordinate catalogs (created by CATALOG or
-   * DELEGATE* entries) get a copy of the set of readers present in
-   * the primary catalog when they are created. Readers added subsequently
-   * will not be available. For this reason, it is best to add all
-   * of the readers before the first call to parse a catalog.</p>
-   *
-   * @param mimeType The MIME type associated with this reader.
-   * @param reader The CatalogReader to use.
-   */
-  public void addReader(String mimeType, CatalogReader reader) {
-    if (readerMap.containsKey(mimeType)) {
-      Integer pos = (Integer) readerMap.get(mimeType);
-      readerArr.set(pos.intValue(), reader);
-    } else {
-      readerArr.add(reader);
-      Integer pos = new Integer(readerArr.size()-1);
-      readerMap.put(mimeType, pos);
-    }
-  }
-
-  /**
-   * Copies the reader list from the current Catalog to a new Catalog.
-   *
-   * <p>This method is used internally when constructing a new catalog.
-   * It copies the current reader associations over to the new catalog.
-   * </p>
-   *
-   * @param newCatalog The new Catalog.
-   */
-  protected void copyReaders(Catalog newCatalog) {
-    // Have to copy the readers in the right order...convert hash to arr
-    Vector mapArr = new Vector(readerMap.size());
-
-    // Pad the mapArr out to the right length
-    for (int count = 0; count < readerMap.size(); count++) {
-      mapArr.add(null);
-    }
-
-    Enumeration en = readerMap.keys();
-    while (en.hasMoreElements()) {
-      String mimeType = (String) en.nextElement();
-      Integer pos = (Integer) readerMap.get(mimeType);
-      mapArr.set(pos.intValue(), mimeType);
-    }
-
-    for (int count = 0; count < mapArr.size(); count++) {
-      String mimeType = (String) mapArr.get(count);
-      Integer pos = (Integer) readerMap.get(mimeType);
-      newCatalog.addReader(mimeType,
-			   (CatalogReader)
-			   readerArr.get(pos.intValue()));
-    }
-  }
-
-  /**
-   * Create a new Catalog object.
-   *
-   * <p>This method constructs a new instance of the running Catalog
-   * class (which might be a subtype of org.apache.xml.resolver.Catalog).
-   * All new catalogs are managed by the same CatalogManager.
-   * </p>
-   *
-   * <p>N.B. All Catalog subtypes should call newCatalog() to construct
-   * a new Catalog. Do not simply use "new Subclass()" since that will
-   * confuse future subclasses.</p>
-   */
-  protected Catalog newCatalog() {
-    String catalogClass = this.getClass().getName();
-
-    try {
-      Catalog c = (Catalog) (Class.forName(catalogClass).newInstance());
-      c.setCatalogManager(catalogManager);
-      copyReaders(c);
-      return c;
-    } catch (ClassNotFoundException cnfe) {
-      catalogManager.debug.message(1, "Class Not Found Exception: " + catalogClass);
-    } catch (IllegalAccessException iae) {
-      catalogManager.debug.message(1, "Illegal Access Exception: " + catalogClass);
-    } catch (InstantiationException ie) {
-      catalogManager.debug.message(1, "Instantiation Exception: " + catalogClass);
-    } catch (ClassCastException cce) {
-      catalogManager.debug.message(1, "Class Cast Exception: " + catalogClass);
-    } catch (Exception e) {
-      catalogManager.debug.message(1, "Other Exception: " + catalogClass);
-    }
-
-    Catalog c = new Catalog();
-    c.setCatalogManager(catalogManager);
-    copyReaders(c);
-    return c;
-  }
-
-  /**
-   * Returns the current base URI.
-   */
-  public String getCurrentBase() {
-    return base.toString();
-  }
-
-  /**
-   * Returns the default override setting associated with this
-   * catalog.
-   *
-   * <p>All catalog files loaded by this catalog will have the
-   * initial override setting specified by this default.</p>
-   */
-  public String getDefaultOverride() {
-    if (default_override) {
-      return "yes";
-    } else {
-      return "no";
-    }
-  }
-
-  /**
-   * Load the system catalog files.
-   *
-   * <p>The method adds all of the
-   * catalogs specified in the <tt>xml.catalog.files</tt> property
-   * to the Catalog list.</p>
-   *
-   * @throws MalformedURLException  One of the system catalogs is
-   * identified with a filename that is not a valid URL.
-   * @throws IOException One of the system catalogs cannot be read.
-   */
-  public void loadSystemCatalogs()
-    throws MalformedURLException, IOException {
-
-    Vector catalogs = catalogManager.getCatalogFiles();
-    if (catalogs != null) {
-      for (int count = 0; count < catalogs.size(); count++) {
-	catalogFiles.addElement(catalogs.elementAt(count));
-      }
-    }
-
-    if (catalogFiles.size() > 0) {
-      // This is a little odd. The parseCatalog() method expects
-      // a filename, but it adds that name to the end of the
-      // catalogFiles vector, and then processes that vector.
-      // This allows the system to handle CATALOG entries
-      // correctly.
-      //
-      // In this init case, we take the last element off the
-      // catalogFiles vector and pass it to parseCatalog. This
-      // will "do the right thing" in the init case, and allow
-      // parseCatalog() to do the right thing in the non-init
-      // case. Honest.
-      //
-      String catfile = (String) catalogFiles.lastElement();
-      catalogFiles.removeElement(catfile);
-      parseCatalog(catfile);
-    }
-  }
-
-  /**
-   * Parse a catalog file, augmenting internal data structures.
-   *
-   * @param fileName The filename of the catalog file to process
-   *
-   * @throws MalformedURLException The fileName cannot be turned into
-   * a valid URL.
-   * @throws IOException Error reading catalog file.
-   */
-  public synchronized void parseCatalog(String fileName)
-    throws MalformedURLException, IOException {
-
-    default_override = catalogManager.getPreferPublic();
-    catalogManager.debug.message(4, "Parse catalog: " + fileName);
-
-    // Put the file into the list of catalogs to process...
-    // In all cases except the case when initCatalog() is the
-    // caller, this will be the only catalog initially in the list...
-    catalogFiles.addElement(fileName);
-
-    // Now process all the pending catalogs...
-    parsePendingCatalogs();
-  }
-
-  /**
-   * Parse a catalog file, augmenting internal data structures.
-   *
-   * <p>Catalogs retrieved over the net may have an associated MIME type.
-   * The MIME type can be used to select an appropriate reader.</p>
-   *
-   * @param mimeType The MIME type of the catalog file.
-   * @param is The InputStream from which the catalog should be read
-   *
-   * @throws CatalogException Failed to load catalog
-   * mimeType.
-   * @throws IOException Error reading catalog file.
-   */
-  public synchronized void parseCatalog(String mimeType, InputStream is)
-    throws IOException, CatalogException {
-
-    default_override = catalogManager.getPreferPublic();
-    catalogManager.debug.message(4, "Parse " + mimeType + " catalog on input \
                stream");
-
-    CatalogReader reader = null;
-
-    if (readerMap.containsKey(mimeType)) {
-      int arrayPos = ((Integer) readerMap.get(mimeType)).intValue();
-      reader = (CatalogReader) readerArr.get(arrayPos);
-    }
-
-    if (reader == null) {
-      String msg = "No CatalogReader for MIME type: " + mimeType;
-      catalogManager.debug.message(2, msg);
-      throw new CatalogException(CatalogException.UNPARSEABLE, msg);
-    }
-
-    reader.readCatalog(this, is);
-
-    // Now process all the pending catalogs...
-    parsePendingCatalogs();
-  }
-
-  /**
-   * Parse a catalog document, augmenting internal data structures.
-   *
-   * <p>This method supports catalog files stored in jar files: e.g.,
-   * jar:file:///path/to/filename.jar!/path/to/catalog.xml". That URI
-   * doesn't survive transmogrification through the URI processing that
-   * the parseCatalog(String) performs and passing it as an input stream
-   * doesn't set the base URI appropriately.</p>
-   *
-   * <p>Written by Stefan Wachter (2002-09-26)</p>
-   *
-   * @param aUrl The URL of the catalog document to process
-   *
-   * @throws IOException Error reading catalog file.
-   */
-  public synchronized void parseCatalog(URL aUrl) throws IOException {
-    catalogCwd = aUrl;
-    base = aUrl;
-
-    default_override = catalogManager.getPreferPublic();
-    catalogManager.debug.message(4, "Parse catalog: " + aUrl.toString());
-
-    DataInputStream inStream = null;
-    boolean parsed = false;
-
-    for (int count = 0; !parsed && count < readerArr.size(); count++) {
-      CatalogReader reader = (CatalogReader) readerArr.get(count);
-
-      try {
-      	inStream = new DataInputStream(aUrl.openStream());
-      } catch (FileNotFoundException fnfe) {
-        // No catalog; give up!
-        break;
-      }
-
-      try {
-        reader.readCatalog(this, inStream);
-        parsed=true;
-      } catch (CatalogException ce) {
-        if (ce.getExceptionType() == CatalogException.PARSE_FAILED) {
-          // give up!
-          break;
+    /** The OVERRIDE Catalog Entry type. */
+    public static final int OVERRIDE = CatalogEntry.addEntryType("OVERRIDE", 1);
+
+    /** The SGMLDECL Catalog Entry type. */
+    public static final int SGMLDECL = CatalogEntry.addEntryType("SGMLDECL", 1);
+
+    /** The DELEGATE_PUBLIC Catalog Entry type. */
+    public static final int DELEGATE_PUBLIC = \
CatalogEntry.addEntryType("DELEGATE_PUBLIC", 2); +
+    /** The DELEGATE_SYSTEM Catalog Entry type. */
+    public static final int DELEGATE_SYSTEM = \
CatalogEntry.addEntryType("DELEGATE_SYSTEM", 2); +
+    /** The DELEGATE_URI Catalog Entry type. */
+    public static final int DELEGATE_URI = CatalogEntry.addEntryType("DELEGATE_URI", \
2); +
+    /** The DOCTYPE Catalog Entry type. */
+    public static final int DOCTYPE  = CatalogEntry.addEntryType("DOCTYPE", 2);
+
+    /** The DTDDECL Catalog Entry type. */
+    public static final int DTDDECL  = CatalogEntry.addEntryType("DTDDECL", 2);
+
+    /** The ENTITY Catalog Entry type. */
+    public static final int ENTITY   = CatalogEntry.addEntryType("ENTITY", 2);
+
+    /** The LINKTYPE Catalog Entry type. */
+    public static final int LINKTYPE = CatalogEntry.addEntryType("LINKTYPE", 2);
+
+    /** The NOTATION Catalog Entry type. */
+    public static final int NOTATION = CatalogEntry.addEntryType("NOTATION", 2);
+
+    /** The PUBLIC Catalog Entry type. */
+    public static final int PUBLIC   = CatalogEntry.addEntryType("PUBLIC", 2);
+
+    /** The SYSTEM Catalog Entry type. */
+    public static final int SYSTEM   = CatalogEntry.addEntryType("SYSTEM", 2);
+
+    /** The URI Catalog Entry type. */
+    public static final int URI      = CatalogEntry.addEntryType("URI", 2);
+
+    /** The REWRITE_SYSTEM Catalog Entry type. */
+    public static final int REWRITE_SYSTEM = \
CatalogEntry.addEntryType("REWRITE_SYSTEM", 2); +
+    /** The REWRITE_URI Catalog Entry type. */
+    public static final int REWRITE_URI = CatalogEntry.addEntryType("REWRITE_URI", \
2); +    /** The SYSTEM_SUFFIX Catalog Entry type. */
+    public static final int SYSTEM_SUFFIX = \
CatalogEntry.addEntryType("SYSTEM_SUFFIX", 2); +    /** The URI_SUFFIX Catalog Entry \
type. */ +    public static final int URI_SUFFIX = \
CatalogEntry.addEntryType("URI_SUFFIX", 2); +
+    /**
+     * The base URI for relative system identifiers in the catalog.
+     * This may be changed by BASE entries in the catalog.
+     */
+    protected URL base;
+
+    /** The base URI of the Catalog file currently being parsed. */
+    protected URL catalogCwd;
+
+    /** The catalog entries currently known to the system. */
+    protected Vector catalogEntries = new Vector();
+
+    /** The default initial override setting. */
+    protected boolean default_override = true;
+
+    /** The catalog manager in use for this instance. */
+    protected CatalogManager catalogManager = CatalogManager.getStaticManager();
+
+    /**
+     * A vector of catalog files to be loaded.
+     *
+     * <p>This list is initially established by
+     * <code>loadSystemCatalogs</code> when
+     * it parses the system catalog list, but CATALOG entries may
+     * contribute to it during the course of parsing.</p>
+     *
+     * @see #loadSystemCatalogs
+     * @see #localCatalogFiles
+     */
+    protected Vector catalogFiles = new Vector();
+
+    /**
+     * A vector of catalog files constructed during processing of
+     * CATALOG entries in the current catalog.
+     *
+     * <p>This two-level system is actually necessary to correctly implement
+     * the semantics of the CATALOG entry. If one catalog file includes
+     * another with a CATALOG entry, the included catalog logically
+     * occurs <i>at the end</i> of the including catalog, and after any
+     * preceding CATALOG entries. In other words, the CATALOG entry
+     * cannot insert anything into the middle of a catalog file.</p>
+     *
+     * <p>When processing reaches the end of each catalog files, any
+     * elements on this vector are added to the front of the
+     * <code>catalogFiles</code> vector.</p>
+     *
+     * @see #catalogFiles
+     */
+    protected Vector localCatalogFiles = new Vector();
+
+    /**
+     * A vector of Catalogs.
+     *
+     * <p>The semantics of Catalog resolution are such that each
+     * catalog is effectively a list of Catalogs (in other words,
+     * a recursive list of Catalog instances).</p>
+     *
+     * <p>Catalogs that are processed as the result of CATALOG or
+     * DELEGATE* entries are subordinate to the catalog that contained
+     * them, but they may in turn have subordinate catalogs.</p>
+     *
+     * <p>Catalogs are only loaded when they are needed, so this vector
+     * initially contains a list of Catalog filenames (URLs). If, during
+     * processing, one of these catalogs has to be loaded, the resulting
+     * Catalog object is placed in the vector, effectively caching it
+     * for the next query.</p>
+     */
+    protected Vector catalogs = new Vector();
+
+    /**
+     * A vector of DELEGATE* Catalog entries constructed during
+     * processing of the Catalog.
+     *
+     * <p>This two-level system has two purposes; first, it allows
+     * us to sort the DELEGATE* entries by the length of the partial
+     * public identifier so that a linear search encounters them in
+     * the correct order and second, it puts them all at the end of
+     * the Catalog.</p>
+     *
+     * <p>When processing reaches the end of each catalog file, any
+     * elements on this vector are added to the end of the
+     * <code>catalogEntries</code> vector. This assures that matching
+     * PUBLIC keywords are encountered before DELEGATE* entries.</p>
+     */
+    protected Vector localDelegate = new Vector();
+
+    /**
+     * A hash of CatalogReaders.
+     *
+     * <p>This hash maps MIME types to elements in the readerArr
+     * vector. This allows the Catalog to quickly locate the reader
+     * for a particular MIME type.</p>
+     */
+    protected Hashtable readerMap = new Hashtable();
+
+    /**
+     * A vector of CatalogReaders.
+     *
+     * <p>This vector contains all of the readers in the order that they
+     * were added. In the event that a catalog is read from a file, where
+     * the MIME type is unknown, each reader is attempted in turn until
+     * one succeeds.</p>
+     */
+    protected Vector readerArr = new Vector();
+
+    /**
+     * Constructs an empty Catalog.
+     *
+     * <p>The constructor interrogates the relevant system properties
+     * using the default (static) CatalogManager
+     * and initializes the catalog data structures.</p>
+     */
+    public Catalog() {
+        // nop;
+    }
+
+    /**
+     * Constructs an empty Catalog with a specific CatalogManager.
+     *
+     * <p>The constructor interrogates the relevant system properties
+     * using the specified Catalog Manager
+     * and initializes the catalog data structures.</p>
+     */
+    public Catalog(CatalogManager manager) {
+        catalogManager = manager;
+    }
+
+    /**
+     * Return the CatalogManager used by this catalog.
+     *
+     */
+    public CatalogManager getCatalogManager() {
+        return catalogManager;
+    }
+
+    /**
+     * Establish the CatalogManager used by this catalog.
+     *
+     */
+    public void setCatalogManager(CatalogManager manager) {
+        catalogManager = manager;
+    }
+
+    /**
+     * Setup readers.
+     */
+    public void setupReaders() {
+        SAXParserFactory spf = SAXParserFactory.newInstance();
+        spf.setNamespaceAware(true);
+        spf.setValidating(false);
+
+        SAXCatalogReader saxReader = new SAXCatalogReader(spf);
+
+        saxReader.setCatalogParser(null, "XCatalog",
+                "org.apache.xml.resolver.readers.XCatalogReader");
+
+        saxReader.setCatalogParser(OASISXMLCatalogReader.namespaceName,
+                "catalog",
+                "org.apache.xml.resolver.readers.OASISXMLCatalogReader");
+
+        addReader("application/xml", saxReader);
+
+        TR9401CatalogReader textReader = new TR9401CatalogReader();
+        addReader("text/plain", textReader);
+    }
+
+    /**
+     * Add a new CatalogReader to the Catalog.
+     *
+     * <p>This method allows you to add a new CatalogReader to the
+     * catalog. The reader will be associated with the specified mimeType.
+     * You can only have one reader per mimeType.</p>
+     *
+     * <p>In the absence of a mimeType (e.g., when reading a catalog
+     * directly from a file on the local system), the readers are attempted
+     * in the order that you add them to the Catalog.</p>
+     *
+     * <p>Note that subordinate catalogs (created by CATALOG or
+     * DELEGATE* entries) get a copy of the set of readers present in
+     * the primary catalog when they are created. Readers added subsequently
+     * will not be available. For this reason, it is best to add all
+     * of the readers before the first call to parse a catalog.</p>
+     *
+     * @param mimeType The MIME type associated with this reader.
+     * @param reader The CatalogReader to use.
+     */
+    public void addReader(String mimeType, CatalogReader reader) {
+        if (readerMap.containsKey(mimeType)) {
+            Integer pos = (Integer) readerMap.get(mimeType);
+            readerArr.set(pos.intValue(), reader);
         } else {
-          // try again!
+            readerArr.add(reader);
+            Integer pos = new Integer(readerArr.size()-1);
+            readerMap.put(mimeType, pos);
         }
-      }
+    }
+
+    /**
+     * Copies the reader list from the current Catalog to a new Catalog.
+     *
+     * <p>This method is used internally when constructing a new catalog.
+     * It copies the current reader associations over to the new catalog.
+     * </p>
+     *
+     * @param newCatalog The new Catalog.
+     */
+    protected void copyReaders(Catalog newCatalog) {
+        // Have to copy the readers in the right order...convert hash to arr
+        Vector mapArr = new Vector(readerMap.size());
+
+        // Pad the mapArr out to the right length
+        for (int count = 0; count < readerMap.size(); count++) {
+            mapArr.add(null);
+        }
+
+        Enumeration en = readerMap.keys();
+        while (en.hasMoreElements()) {
+            String mimeType = (String) en.nextElement();
+            Integer pos = (Integer) readerMap.get(mimeType);
+            mapArr.set(pos.intValue(), mimeType);
+        }
+
+        for (int count = 0; count < mapArr.size(); count++) {
+            String mimeType = (String) mapArr.get(count);
+            Integer pos = (Integer) readerMap.get(mimeType);
+            newCatalog.addReader(mimeType,
+                    (CatalogReader)
+                    readerArr.get(pos.intValue()));
+        }
+    }
+
+    /**
+     * Create a new Catalog object.
+     *
+     * <p>This method constructs a new instance of the running Catalog
+     * class (which might be a subtype of org.apache.xml.resolver.Catalog).
+     * All new catalogs are managed by the same CatalogManager.
+     * </p>
+     *
+     * <p>N.B. All Catalog subtypes should call newCatalog() to construct
+     * a new Catalog. Do not simply use "new Subclass()" since that will
+     * confuse future subclasses.</p>
+     */
+    protected Catalog newCatalog() {
+        String catalogClass = this.getClass().getName();
+
+        try {
+            Catalog c = (Catalog) (Class.forName(catalogClass).newInstance());
+            c.setCatalogManager(catalogManager);
+            copyReaders(c);
+            return c;
+        } catch (ClassNotFoundException cnfe) {
+            catalogManager.debug.message(1, "Class Not Found Exception: " + \
catalogClass); +        } catch (IllegalAccessException iae) {
+            catalogManager.debug.message(1, "Illegal Access Exception: " + \
catalogClass); +        } catch (InstantiationException ie) {
+            catalogManager.debug.message(1, "Instantiation Exception: " + \
catalogClass); +        } catch (ClassCastException cce) {
+            catalogManager.debug.message(1, "Class Cast Exception: " + \
catalogClass); +        } catch (Exception e) {
+            catalogManager.debug.message(1, "Other Exception: " + catalogClass);
+        }
+
+        Catalog c = new Catalog();
+        c.setCatalogManager(catalogManager);
+        copyReaders(c);
+        return c;
+    }
+
+    /**
+     * Returns the current base URI.
+     */
+    public String getCurrentBase() {
+        return base.toString();
+    }
+
+    /**
+     * Returns the default override setting associated with this
+     * catalog.
+     *
+     * <p>All catalog files loaded by this catalog will have the
+     * initial override setting specified by this default.</p>
+     */
+    public String getDefaultOverride() {
+        if (default_override) {
+            return "yes";
+        } else {
+            return "no";
+        }
+    }
+
+    /**
+     * Load the system catalog files.
+     *
+     * <p>The method adds all of the
+     * catalogs specified in the <tt>xml.catalog.files</tt> property
+     * to the Catalog list.</p>
+     *
+     * @throws MalformedURLException  One of the system catalogs is
+     * identified with a filename that is not a valid URL.
+     * @throws IOException One of the system catalogs cannot be read.
+     */
+    public void loadSystemCatalogs()
+            throws MalformedURLException, IOException {
+
+        Vector catalogs = catalogManager.getCatalogFiles();
+        if (catalogs != null) {
+            for (int count = 0; count < catalogs.size(); count++) {
+                catalogFiles.addElement(catalogs.elementAt(count));
+            }
+        }
+
+        if (catalogFiles.size() > 0) {
+            // This is a little odd. The parseCatalog() method expects
+            // a filename, but it adds that name to the end of the
+            // catalogFiles vector, and then processes that vector.
+            // This allows the system to handle CATALOG entries
+            // correctly.
+            //
+            // In this init case, we take the last element off the
+            // catalogFiles vector and pass it to parseCatalog. This
+            // will "do the right thing" in the init case, and allow
+            // parseCatalog() to do the right thing in the non-init
+            // case. Honest.
+            //
+            String catfile = (String) catalogFiles.lastElement();
+            catalogFiles.removeElement(catfile);
+            parseCatalog(catfile);
+        }
+    }
+
+    /**
+     * Parse a catalog file, augmenting internal data structures.
+     *
+     * @param fileName The filename of the catalog file to process
+     *
+     * @throws MalformedURLException The fileName cannot be turned into
+     * a valid URL.
+     * @throws IOException Error reading catalog file.
+     */
+    public synchronized void parseCatalog(String fileName)
+            throws MalformedURLException, IOException {
+
+        default_override = catalogManager.getPreferPublic();
+        catalogManager.debug.message(4, "Parse catalog: " + fileName);
+
+        // Put the file into the list of catalogs to process...
+        // In all cases except the case when initCatalog() is the
+        // caller, this will be the only catalog initially in the list...
+        catalogFiles.addElement(fileName);
+
+        // Now process all the pending catalogs...
+        parsePendingCatalogs();
+    }
+
+    /**
+     * Parse a catalog file, augmenting internal data structures.
+     *
+     * <p>Catalogs retrieved over the net may have an associated MIME type.
+     * The MIME type can be used to select an appropriate reader.</p>
+     *
+     * @param mimeType The MIME type of the catalog file.
+     * @param is The InputStream from which the catalog should be read
+     *
+     * @throws CatalogException Failed to load catalog
+     * mimeType.
+     * @throws IOException Error reading catalog file.
+     */
+    public synchronized void parseCatalog(String mimeType, InputStream is)
+            throws IOException, CatalogException {
+
+        default_override = catalogManager.getPreferPublic();
+        catalogManager.debug.message(4, "Parse " + mimeType + " catalog on input \
stream"); +
+        CatalogReader reader = null;
+
+        if (readerMap.containsKey(mimeType)) {
+            int arrayPos = ((Integer) readerMap.get(mimeType)).intValue();
+            reader = (CatalogReader) readerArr.get(arrayPos);
+        }
+
+        if (reader == null) {
+            String msg = "No CatalogReader for MIME type: " + mimeType;
+            catalogManager.debug.message(2, msg);
+            throw new CatalogException(CatalogException.UNPARSEABLE, msg);
+        }
+
+        reader.readCatalog(this, is);
+
+        // Now process all the pending catalogs...
+        parsePendingCatalogs();
+    }
+
+    /**
+     * Parse a catalog document, augmenting internal data structures.
+     *
+     * <p>This method supports catalog files stored in jar files: e.g.,
+     * jar:file:///path/to/filename.jar!/path/to/catalog.xml". That URI
+     * doesn't survive transmogrification through the URI processing that
+     * the parseCatalog(String) performs and passing it as an input stream
+     * doesn't set the base URI appropriately.</p>
+     *
+     * <p>Written by Stefan Wachter (2002-09-26)</p>
+     *
+     * @param aUrl The URL of the catalog document to process
+     *
+     * @throws IOException Error reading catalog file.
+     */
+    public synchronized void parseCatalog(URL aUrl) throws IOException {
+        catalogCwd = aUrl;
+        base = aUrl;
+
+        default_override = catalogManager.getPreferPublic();
+        catalogManager.debug.message(4, "Parse catalog: " + aUrl.toString());
+
+        DataInputStream inStream = null;
+        boolean parsed = false;
+
+        for (int count = 0; !parsed && count < readerArr.size(); count++) {
+            CatalogReader reader = (CatalogReader) readerArr.get(count);
+
+            try {
+                inStream = new DataInputStream(aUrl.openStream());
+            } catch (FileNotFoundException fnfe) {
+                // No catalog; give up!
+                break;
+            }
+
+            try {
+                reader.readCatalog(this, inStream);
+                parsed=true;
+            } catch (CatalogException ce) {
+                if (ce.getExceptionType() == CatalogException.PARSE_FAILED) {
+                    // give up!
+                    break;
+                } else {
+                    // try again!
+                }
+            }
+
+            try {
+                inStream.close();
+            } catch (IOException e) {
+                //nop
+            }
+        }
+
+        if (parsed) parsePendingCatalogs();
+    }
+
+    /**
+     * Parse all of the pending catalogs.
+     *
+     * <p>Catalogs may refer to other catalogs, this method parses
+     * all of the currently pending catalog files.</p>
+     */
+    protected synchronized void parsePendingCatalogs()
+            throws MalformedURLException, IOException {
+
+        if (!localCatalogFiles.isEmpty()) {
+            // Move all the localCatalogFiles into the front of
+            // the catalogFiles queue
+            Vector newQueue = new Vector();
+            Enumeration q = localCatalogFiles.elements();
+            while (q.hasMoreElements()) {
+                newQueue.addElement(q.nextElement());
+            }
+
+            // Put the rest of the catalogs on the end of the new list
+            for (int curCat = 0; curCat < catalogFiles.size(); curCat++) {
+                String catfile = (String) catalogFiles.elementAt(curCat);
+                newQueue.addElement(catfile);
+            }
+
+            catalogFiles = newQueue;
+            localCatalogFiles.clear();
+        }
+
+        // Suppose there are no catalog files to process, but the
+        // single catalog already parsed included some delegate
+        // entries? Make sure they don't get lost.
+        if (catalogFiles.isEmpty() && !localDelegate.isEmpty()) {
+            Enumeration e = localDelegate.elements();
+            while (e.hasMoreElements()) {
+                catalogEntries.addElement(e.nextElement());
+            }
+            localDelegate.clear();
+        }
+
+        // Now process all the files on the catalogFiles vector. This
+        // vector can grow during processing if CATALOG entries are
+        // encountered in the catalog
+        while (!catalogFiles.isEmpty()) {
+            String catfile = (String) catalogFiles.elementAt(0);
+            try {
+                catalogFiles.remove(0);
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // can't happen
+            }
+
+            if (catalogEntries.size() == 0 && catalogs.size() == 0) {
+                // We haven't parsed any catalogs yet, let this
+                // catalog be the first...
+                try {
+                    parseCatalogFile(catfile);
+                } catch (CatalogException ce) {
+                    System.out.println("FIXME: " + ce.toString());
+                }
+            } else {
+                // This is a subordinate catalog. We save its name,
+                // but don't bother to load it unless it's necessary.
+                catalogs.addElement(catfile);
+            }
+
+            if (!localCatalogFiles.isEmpty()) {
+                // Move all the localCatalogFiles into the front of
+                // the catalogFiles queue
+                Vector newQueue = new Vector();
+                Enumeration q = localCatalogFiles.elements();
+                while (q.hasMoreElements()) {
+                    newQueue.addElement(q.nextElement());
+                }
+
+                // Put the rest of the catalogs on the end of the new list
+                for (int curCat = 0; curCat < catalogFiles.size(); curCat++) {
+                    catfile = (String) catalogFiles.elementAt(curCat);
+                    newQueue.addElement(catfile);
+                }
+
+                catalogFiles = newQueue;
+                localCatalogFiles.clear();
+            }
+
+            if (!localDelegate.isEmpty()) {
+                Enumeration e = localDelegate.elements();
+                while (e.hasMoreElements()) {
+                    catalogEntries.addElement(e.nextElement());
+                }
+                localDelegate.clear();
+            }
+        }
+
+        // We've parsed them all, reinit the vector...
+        catalogFiles.clear();
+    }
+
+    /**
+     * Parse a single catalog file, augmenting internal data structures.
+     *
+     * @param fileName The filename of the catalog file to process
+     *
+     * @throws MalformedURLException The fileName cannot be turned into
+     * a valid URL.
+     * @throws IOException Error reading catalog file.
+     */
+    protected synchronized void parseCatalogFile(String fileName)
+            throws MalformedURLException, IOException, CatalogException {
+
+        CatalogEntry entry;
+
+        // The base-base is the cwd. If the catalog file is specified
+        // with a relative path, this assures that it gets resolved
+        // properly...
+        try {
+            // tack on a basename because URLs point to files not dirs
+            catalogCwd = FileURL.makeURL("basename");
+        } catch (MalformedURLException e) {
+            String userdir = SecuritySupport.getSystemProperty("user.dir");
+            userdir = userdir.replace('\\', '/');
+            catalogManager.debug.message(1, "Malformed URL on cwd", userdir);
+            catalogCwd = null;
+        }
+
+        // The initial base URI is the location of the catalog file
+        try {
+            base = new URL(catalogCwd, fixSlashes(fileName));
+        } catch (MalformedURLException e) {
+            try {
+                base = new URL("file:" + fixSlashes(fileName));
+            } catch (MalformedURLException e2) {
+                catalogManager.debug.message(1, "Malformed URL on catalog filename",
+                        fixSlashes(fileName));
+                base = null;
+            }
+        }
+
+        catalogManager.debug.message(2, "Loading catalog", fileName);
+        catalogManager.debug.message(4, "Default BASE", base.toString());
+
+        fileName = base.toString();
+
+        DataInputStream inStream = null;
+        boolean parsed = false;
+        boolean notFound = false;
+
+        for (int count = 0; !parsed && count < readerArr.size(); count++) {
+            CatalogReader reader = (CatalogReader) readerArr.get(count);
+
+            try {
+                notFound = false;
+                inStream = new DataInputStream(base.openStream());
+            } catch (FileNotFoundException fnfe) {
+                // No catalog; give up!
+                notFound = true;
+                break;
+            }
+
+            try {
+                reader.readCatalog(this, inStream);
+                parsed = true;
+            } catch (CatalogException ce) {
+                if (ce.getExceptionType() == CatalogException.PARSE_FAILED) {
+                    // give up!
+                    break;
+                } else {
+                    // try again!
+                }
+            }
+
+            try {
+                inStream.close();
+            } catch (IOException e) {
+                //nop
+            }
+        }
+
+        if (!parsed) {
+            if (notFound) {
+                catalogManager.debug.message(3, "Catalog does not exist", fileName);
+            } else {
+                catalogManager.debug.message(1, "Failed to parse catalog", \
fileName); +            }
+        }
+    }
+
+    /**
+     * Cleanup and process a Catalog entry.
+     *
+     * <p>This method processes each Catalog entry, changing mapped
+     * relative system identifiers into absolute ones (based on the current
+     * base URI), and maintaining other information about the current
+     * catalog.</p>
+     *
+     * @param entry The CatalogEntry to process.
+     */
+    public void addEntry(CatalogEntry entry) {
+        int type = entry.getEntryType();
+
+        if (type == BASE) {
+            String value = entry.getEntryArg(0);
+            URL newbase = null;
+
+            if (base == null) {
+                catalogManager.debug.message(5, "BASE CUR", "null");
+            } else {
+                catalogManager.debug.message(5, "BASE CUR", base.toString());
+            }
+            catalogManager.debug.message(4, "BASE STR", value);
+
+            try {
+                value = fixSlashes(value);
+                newbase = new URL(base, value);
+            } catch (MalformedURLException e) {
+                try {
+                    newbase = new URL("file:" + value);
+                } catch (MalformedURLException e2) {
+                    catalogManager.debug.message(1, "Malformed URL on base", value);
+                    newbase = null;
+                }
+            }
+
+            if (newbase != null) {
+                base = newbase;
+            }
+
+            catalogManager.debug.message(5, "BASE NEW", base.toString());
+        } else if (type == CATALOG) {
+            String fsi = makeAbsolute(entry.getEntryArg(0));
+
+            catalogManager.debug.message(4, "CATALOG", fsi);
+
+            localCatalogFiles.addElement(fsi);
+        } else if (type == PUBLIC) {
+            String publicid = PublicId.normalize(entry.getEntryArg(0));
+            String systemid = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
+
+            entry.setEntryArg(0, publicid);
+            entry.setEntryArg(1, systemid);
+
+            catalogManager.debug.message(4, "PUBLIC", publicid, systemid);
+
+            catalogEntries.addElement(entry);
+        } else if (type == SYSTEM) {
+            String systemid = normalizeURI(entry.getEntryArg(0));
+            String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
+
+            entry.setEntryArg(1, fsi);
+
+            catalogManager.debug.message(4, "SYSTEM", systemid, fsi);
+
+            catalogEntries.addElement(entry);
+        } else if (type == URI) {
+            String uri = normalizeURI(entry.getEntryArg(0));
+            String altURI = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
 
-      try {
-      	inStream.close();
-      } catch (IOException e) {
-      	//nop
-      }
-    }
-
-    if (parsed) parsePendingCatalogs();
-  }
-
-  /**
-   * Parse all of the pending catalogs.
-   *
-   * <p>Catalogs may refer to other catalogs, this method parses
-   * all of the currently pending catalog files.</p>
-   */
-  protected synchronized void parsePendingCatalogs()
-    throws MalformedURLException, IOException {
-
-    if (!localCatalogFiles.isEmpty()) {
-      // Move all the localCatalogFiles into the front of
-      // the catalogFiles queue
-      Vector newQueue = new Vector();
-      Enumeration q = localCatalogFiles.elements();
-      while (q.hasMoreElements()) {
-	newQueue.addElement(q.nextElement());
-      }
-
-      // Put the rest of the catalogs on the end of the new list
-      for (int curCat = 0; curCat < catalogFiles.size(); curCat++) {
-	String catfile = (String) catalogFiles.elementAt(curCat);
-	newQueue.addElement(catfile);
-      }
-
-      catalogFiles = newQueue;
-      localCatalogFiles.clear();
-    }
-
-    // Suppose there are no catalog files to process, but the
-    // single catalog already parsed included some delegate
-    // entries? Make sure they don't get lost.
-    if (catalogFiles.isEmpty() && !localDelegate.isEmpty()) {
-      Enumeration e = localDelegate.elements();
-      while (e.hasMoreElements()) {
-	catalogEntries.addElement(e.nextElement());
-      }
-      localDelegate.clear();
-    }
-
-    // Now process all the files on the catalogFiles vector. This
-    // vector can grow during processing if CATALOG entries are
-    // encountered in the catalog
-    while (!catalogFiles.isEmpty()) {
-      String catfile = (String) catalogFiles.elementAt(0);
-      try {
-	catalogFiles.remove(0);
-      } catch (ArrayIndexOutOfBoundsException e) {
-	// can't happen
-      }
-
-      if (catalogEntries.size() == 0 && catalogs.size() == 0) {
-	// We haven't parsed any catalogs yet, let this
-	// catalog be the first...
-	try {
-	  parseCatalogFile(catfile);
-	} catch (CatalogException ce) {
-	  System.out.println("FIXME: " + ce.toString());
-	}
-      } else {
-	// This is a subordinate catalog. We save its name,
-	// but don't bother to load it unless it's necessary.
-	catalogs.addElement(catfile);
-      }
-
-      if (!localCatalogFiles.isEmpty()) {
-	// Move all the localCatalogFiles into the front of
-	// the catalogFiles queue
-	Vector newQueue = new Vector();
-	Enumeration q = localCatalogFiles.elements();
-	while (q.hasMoreElements()) {
-	  newQueue.addElement(q.nextElement());
-	}
-
-	// Put the rest of the catalogs on the end of the new list
-	for (int curCat = 0; curCat < catalogFiles.size(); curCat++) {
-	  catfile = (String) catalogFiles.elementAt(curCat);
-	  newQueue.addElement(catfile);
-	}
-
-	catalogFiles = newQueue;
-	localCatalogFiles.clear();
-      }
-
-      if (!localDelegate.isEmpty()) {
-	Enumeration e = localDelegate.elements();
-	while (e.hasMoreElements()) {
-	  catalogEntries.addElement(e.nextElement());
-	}
-	localDelegate.clear();
-      }
-    }
-
-    // We've parsed them all, reinit the vector...
-    catalogFiles.clear();
-  }
-
-  /**
-   * Parse a single catalog file, augmenting internal data structures.
-   *
-   * @param fileName The filename of the catalog file to process
-   *
-   * @throws MalformedURLException The fileName cannot be turned into
-   * a valid URL.
-   * @throws IOException Error reading catalog file.
-   */
-  protected synchronized void parseCatalogFile(String fileName)
-    throws MalformedURLException, IOException, CatalogException {
-
-    CatalogEntry entry;
-
-    // The base-base is the cwd. If the catalog file is specified
-    // with a relative path, this assures that it gets resolved
-    // properly...
-    try {
-      // tack on a basename because URLs point to files not dirs
-      catalogCwd = FileURL.makeURL("basename");
-    } catch (MalformedURLException e) {
-      String userdir = SecuritySupport.getSystemProperty("user.dir");
-      userdir = userdir.replace('\\', '/');
-      catalogManager.debug.message(1, "Malformed URL on cwd", userdir);
-      catalogCwd = null;
-    }
-
-    // The initial base URI is the location of the catalog file
-    try {
-      base = new URL(catalogCwd, fixSlashes(fileName));
-    } catch (MalformedURLException e) {
-      try {
-	base = new URL("file:" + fixSlashes(fileName));
-      } catch (MalformedURLException e2) {
-	catalogManager.debug.message(1, "Malformed URL on catalog filename",
-		      fixSlashes(fileName));
-	base = null;
-      }
-    }
-
-    catalogManager.debug.message(2, "Loading catalog", fileName);
-    catalogManager.debug.message(4, "Default BASE", base.toString());
-
-    fileName = base.toString();
-
-    DataInputStream inStream = null;
-    boolean parsed = false;
-    boolean notFound = false;
-
-    for (int count = 0; !parsed && count < readerArr.size(); count++) {
-      CatalogReader reader = (CatalogReader) readerArr.get(count);
-
-      try {
-	notFound = false;
-	inStream = new DataInputStream(base.openStream());
-      } catch (FileNotFoundException fnfe) {
-	// No catalog; give up!
-	notFound = true;
-	break;
-      }
-
-      try {
-	reader.readCatalog(this, inStream);
-	parsed = true;
-      } catch (CatalogException ce) {
-	if (ce.getExceptionType() == CatalogException.PARSE_FAILED) {
-	  // give up!
-	  break;
-	} else {
-	  // try again!
-	}
-      }
-
-      try {
-	inStream.close();
-      } catch (IOException e) {
-	//nop
-      }
-    }
-
-    if (!parsed) {
-      if (notFound) {
-	catalogManager.debug.message(3, "Catalog does not exist", fileName);
-      } else {
-	catalogManager.debug.message(1, "Failed to parse catalog", fileName);
-      }
-    }
-  }
-
-  /**
-   * Cleanup and process a Catalog entry.
-   *
-   * <p>This method processes each Catalog entry, changing mapped
-   * relative system identifiers into absolute ones (based on the current
-   * base URI), and maintaining other information about the current
-   * catalog.</p>
-   *
-   * @param entry The CatalogEntry to process.
-   */
-  public void addEntry(CatalogEntry entry) {
-    int type = entry.getEntryType();
-
-    if (type == BASE) {
-      String value = entry.getEntryArg(0);
-      URL newbase = null;
-
-      if (base == null) {
-	catalogManager.debug.message(5, "BASE CUR", "null");
-      } else {
-	catalogManager.debug.message(5, "BASE CUR", base.toString());
-      }
-      catalogManager.debug.message(4, "BASE STR", value);
-
-      try {
-	value = fixSlashes(value);
-	newbase = new URL(base, value);
-      } catch (MalformedURLException e) {
-	try {
-	  newbase = new URL("file:" + value);
-	} catch (MalformedURLException e2) {
-	  catalogManager.debug.message(1, "Malformed URL on base", value);
-	  newbase = null;
-	}
-      }
-
-      if (newbase != null) {
-	base = newbase;
-      }
-
-      catalogManager.debug.message(5, "BASE NEW", base.toString());
-    } else if (type == CATALOG) {
-      String fsi = makeAbsolute(entry.getEntryArg(0));
-
-      catalogManager.debug.message(4, "CATALOG", fsi);
-
-      localCatalogFiles.addElement(fsi);
-    } else if (type == PUBLIC) {
-      String publicid = PublicId.normalize(entry.getEntryArg(0));
-      String systemid = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-
-      entry.setEntryArg(0, publicid);
-      entry.setEntryArg(1, systemid);
-
-      catalogManager.debug.message(4, "PUBLIC", publicid, systemid);
-
-      catalogEntries.addElement(entry);
-    } else if (type == SYSTEM) {
-      String systemid = normalizeURI(entry.getEntryArg(0));
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-
-      entry.setEntryArg(1, fsi);
-
-      catalogManager.debug.message(4, "SYSTEM", systemid, fsi);
-
-      catalogEntries.addElement(entry);
-    } else if (type == URI) {
-      String uri = normalizeURI(entry.getEntryArg(0));
-      String altURI = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-
-      entry.setEntryArg(1, altURI);
-
-      catalogManager.debug.message(4, "URI", uri, altURI);
-
-      catalogEntries.addElement(entry);
-    } else if (type == DOCUMENT) {
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(0)));
-      entry.setEntryArg(0, fsi);
-
-      catalogManager.debug.message(4, "DOCUMENT", fsi);
-
-      catalogEntries.addElement(entry);
-    } else if (type == OVERRIDE) {
-      catalogManager.debug.message(4, "OVERRIDE", entry.getEntryArg(0));
-
-      catalogEntries.addElement(entry);
-    } else if (type == SGMLDECL) {
-      // meaningless in XML
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(0)));
-      entry.setEntryArg(0, fsi);
-
-      catalogManager.debug.message(4, "SGMLDECL", fsi);
-
-      catalogEntries.addElement(entry);
-    } else if (type == DELEGATE_PUBLIC) {
-      String ppi = PublicId.normalize(entry.getEntryArg(0));
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-
-      entry.setEntryArg(0, ppi);
-      entry.setEntryArg(1, fsi);
-
-      catalogManager.debug.message(4, "DELEGATE_PUBLIC", ppi, fsi);
-
-      addDelegate(entry);
-    } else if (type == DELEGATE_SYSTEM) {
-      String psi = normalizeURI(entry.getEntryArg(0));
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-
-      entry.setEntryArg(0, psi);
-      entry.setEntryArg(1, fsi);
-
-      catalogManager.debug.message(4, "DELEGATE_SYSTEM", psi, fsi);
-
-      addDelegate(entry);
-    } else if (type == DELEGATE_URI) {
-      String pui = normalizeURI(entry.getEntryArg(0));
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-
-      entry.setEntryArg(0, pui);
-      entry.setEntryArg(1, fsi);
-
-      catalogManager.debug.message(4, "DELEGATE_URI", pui, fsi);
-
-      addDelegate(entry);
-    } else if (type == REWRITE_SYSTEM) {
-      String psi = normalizeURI(entry.getEntryArg(0));
-      String rpx = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-
-      entry.setEntryArg(0, psi);
-      entry.setEntryArg(1, rpx);
-
-      catalogManager.debug.message(4, "REWRITE_SYSTEM", psi, rpx);
-
-      catalogEntries.addElement(entry);
-    } else if (type == REWRITE_URI) {
-      String pui = normalizeURI(entry.getEntryArg(0));
-      String upx = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-
-      entry.setEntryArg(0, pui);
-      entry.setEntryArg(1, upx);
-
-      catalogManager.debug.message(4, "REWRITE_URI", pui, upx);
-
-      catalogEntries.addElement(entry);
-    } else if (type == SYSTEM_SUFFIX) {
-      String pui = normalizeURI(entry.getEntryArg(0));
-      String upx = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-
-      entry.setEntryArg(0, pui);
-      entry.setEntryArg(1, upx);
-
-      catalogManager.debug.message(4, "SYSTEM_SUFFIX", pui, upx);
-
-      catalogEntries.addElement(entry);
-    } else if (type == URI_SUFFIX) {
-      String pui = normalizeURI(entry.getEntryArg(0));
-      String upx = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-
-      entry.setEntryArg(0, pui);
-      entry.setEntryArg(1, upx);
-
-      catalogManager.debug.message(4, "URI_SUFFIX", pui, upx);
-
-      catalogEntries.addElement(entry);
-    } else if (type == DOCTYPE) {
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-      entry.setEntryArg(1, fsi);
-
-      catalogManager.debug.message(4, "DOCTYPE", entry.getEntryArg(0), fsi);
-
-      catalogEntries.addElement(entry);
-    } else if (type == DTDDECL) {
-      // meaningless in XML
-      String fpi = PublicId.normalize(entry.getEntryArg(0));
-      entry.setEntryArg(0, fpi);
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-      entry.setEntryArg(1, fsi);
-
-      catalogManager.debug.message(4, "DTDDECL", fpi, fsi);
-
-      catalogEntries.addElement(entry);
-    } else if (type == ENTITY) {
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-      entry.setEntryArg(1, fsi);
-
-      catalogManager.debug.message(4, "ENTITY", entry.getEntryArg(0), fsi);
-
-      catalogEntries.addElement(entry);
-    } else if (type == LINKTYPE) {
-      // meaningless in XML
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-      entry.setEntryArg(1, fsi);
-
-      catalogManager.debug.message(4, "LINKTYPE", entry.getEntryArg(0), fsi);
-
-      catalogEntries.addElement(entry);
-    } else if (type == NOTATION) {
-      String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
-      entry.setEntryArg(1, fsi);
-
-      catalogManager.debug.message(4, "NOTATION", entry.getEntryArg(0), fsi);
-
-      catalogEntries.addElement(entry);
-    } else {
-      catalogEntries.addElement(entry);
-    }
-  }
-
-  /**
-   * Handle unknown CatalogEntry types.
-   *
-   * <p>This method exists to allow subclasses to deal with unknown
-   * entry types.</p>
-   */
-  public void unknownEntry(Vector strings) {
-    if (strings != null && strings.size() > 0) {
-      String keyword = (String) strings.elementAt(0);
-      catalogManager.debug.message(2, "Unrecognized token parsing catalog", \
                keyword);
-    }
-  }
-
-  /**
-   * Parse all subordinate catalogs.
-   *
-   * <p>This method recursively parses all of the subordinate catalogs.
-   * If this method does not throw an exception, you can be confident that
-   * no subsequent call to any resolve*() method will either, with two
-   * possible exceptions:</p>
-   *
-   * <ol>
-   * <li><p>Delegated catalogs are re-parsed each time they are needed
-   * (because a variable list of them may be needed in each case,
-   * depending on the length of the matching partial public identifier).</p>
-   * <p>But they are parsed by this method, so as long as they don't
-   * change or disappear while the program is running, they shouldn't
-   * generate errors later if they don't generate errors now.</p>
-   * <li><p>If you add new catalogs with <code>parseCatalog</code>, they
-   * won't be loaded until they are needed or until you call
-   * <code>parseAllCatalogs</code> again.</p>
-   * </ol>
-   *
-   * <p>On the other hand, if you don't call this method, you may
-   * successfully parse documents without having to load all possible
-   * catalogs.</p>
-   *
-   * @throws MalformedURLException The filename (URL) for a
-   * subordinate or delegated catalog is not a valid URL.
-   * @throws IOException Error reading some subordinate or delegated
-   * catalog file.
-   */
-  public void parseAllCatalogs()
-    throws MalformedURLException, IOException {
-
-    // Parse all the subordinate catalogs
-    for (int catPos = 0; catPos < catalogs.size(); catPos++) {
-      Catalog c = null;
-
-      try {
-	c = (Catalog) catalogs.elementAt(catPos);
-      } catch (ClassCastException e) {
-	String catfile = (String) catalogs.elementAt(catPos);
-	c = newCatalog();
-
-	c.parseCatalog(catfile);
-	catalogs.setElementAt(c, catPos);
-	c.parseAllCatalogs();
-      }
-    }
-
-    // Parse all the DELEGATE catalogs
-    Enumeration en = catalogEntries.elements();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-      if (e.getEntryType() == DELEGATE_PUBLIC
-	  || e.getEntryType() == DELEGATE_SYSTEM
-	  || e.getEntryType() == DELEGATE_URI) {
-	Catalog dcat = newCatalog();
-	dcat.parseCatalog(e.getEntryArg(1));
-      }
-    }
-  }
-
-
-  /**
-   * Return the applicable DOCTYPE system identifier.
-   *
-   * @param entityName The name of the entity (element) for which
-   * a doctype is required.
-   * @param publicId The nominal public identifier for the doctype
-   * (as provided in the source document).
-   * @param systemId The nominal system identifier for the doctype
-   * (as provided in the source document).
-   *
-   * @return The system identifier to use for the doctype.
-   *
-   * @throws MalformedURLException The formal system identifier of a
-   * subordinate catalog cannot be turned into a valid URL.
-   * @throws IOException Error reading subordinate catalog file.
-   */
-  public String resolveDoctype(String entityName,
-			       String publicId,
-			       String systemId)
-    throws MalformedURLException, IOException {
-    String resolved = null;
-
-    catalogManager.debug.message(3, "resolveDoctype("
-		  +entityName+","+publicId+","+systemId+")");
-
-    systemId = normalizeURI(systemId);
-
-    if (publicId != null && publicId.startsWith("urn:publicid:")) {
-      publicId = PublicId.decodeURN(publicId);
-    }
-
-    if (systemId != null && systemId.startsWith("urn:publicid:")) {
-      systemId = PublicId.decodeURN(systemId);
-      if (publicId != null && !publicId.equals(systemId)) {
-	catalogManager.debug.message(1, "urn:publicid: system identifier differs from \
                public identifier; using public identifier");
-	systemId = null;
-      } else {
-	publicId = systemId;
-	systemId = null;
-      }
-    }
-
-    if (systemId != null) {
-      // If there's a SYSTEM entry in this catalog, use it
-      resolved = resolveLocalSystem(systemId);
-      if (resolved != null) {
-	return resolved;
-      }
-    }
-
-    if (publicId != null) {
-      // If there's a PUBLIC entry in this catalog, use it
-      resolved = resolveLocalPublic(DOCTYPE,
-				    entityName,
-				    publicId,
-				    systemId);
-      if (resolved != null) {
-	return resolved;
-      }
-    }
-
-    // If there's a DOCTYPE entry in this catalog, use it
-    boolean over = default_override;
-    Enumeration en = catalogEntries.elements();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-      if (e.getEntryType() == OVERRIDE) {
-	over = e.getEntryArg(0).equalsIgnoreCase("YES");
-	continue;
-      }
-
-      if (e.getEntryType() == DOCTYPE
-	  && e.getEntryArg(0).equals(entityName)) {
-	if (over || systemId == null) {
-	  return e.getEntryArg(1);
-	}
-      }
-    }
-
-    // Otherwise, look in the subordinate catalogs
-    return resolveSubordinateCatalogs(DOCTYPE,
-				      entityName,
-				      publicId,
-				      systemId);
-  }
-
-  /**
-   * Return the applicable DOCUMENT entry.
-   *
-   * @return The system identifier to use for the doctype.
-   *
-   * @throws MalformedURLException The formal system identifier of a
-   * subordinate catalog cannot be turned into a valid URL.
-   * @throws IOException Error reading subordinate catalog file.
-   */
-  public String resolveDocument()
-    throws MalformedURLException, IOException {
-    // If there's a DOCUMENT entry, return it
-
-    catalogManager.debug.message(3, "resolveDocument");
-
-    Enumeration en = catalogEntries.elements();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-      if (e.getEntryType() == DOCUMENT) {
-	return e.getEntryArg(0);
-      }
-    }
-
-    return resolveSubordinateCatalogs(DOCUMENT,
-				      null, null, null);
-  }
-
-  /**
-   * Return the applicable ENTITY system identifier.
-   *
-   * @param entityName The name of the entity for which
-   * a system identifier is required.
-   * @param publicId The nominal public identifier for the entity
-   * (as provided in the source document).
-   * @param systemId The nominal system identifier for the entity
-   * (as provided in the source document).
-   *
-   * @return The system identifier to use for the entity.
-   *
-   * @throws MalformedURLException The formal system identifier of a
-   * subordinate catalog cannot be turned into a valid URL.
-   * @throws IOException Error reading subordinate catalog file.
-   */
-  public String resolveEntity(String entityName,
-			      String publicId,
-			      String systemId)
-    throws MalformedURLException, IOException {
-    String resolved = null;
-
-    catalogManager.debug.message(3, "resolveEntity("
-		  +entityName+","+publicId+","+systemId+")");
-
-    systemId = normalizeURI(systemId);
-
-    if (publicId != null && publicId.startsWith("urn:publicid:")) {
-      publicId = PublicId.decodeURN(publicId);
-    }
-
-    if (systemId != null && systemId.startsWith("urn:publicid:")) {
-      systemId = PublicId.decodeURN(systemId);
-      if (publicId != null && !publicId.equals(systemId)) {
-	catalogManager.debug.message(1, "urn:publicid: system identifier differs from \
                public identifier; using public identifier");
-	systemId = null;
-      } else {
-	publicId = systemId;
-	systemId = null;
-      }
-    }
-
-    if (systemId != null) {
-      // If there's a SYSTEM entry in this catalog, use it
-      resolved = resolveLocalSystem(systemId);
-      if (resolved != null) {
-	return resolved;
-      }
-    }
-
-    if (publicId != null) {
-      // If there's a PUBLIC entry in this catalog, use it
-      resolved = resolveLocalPublic(ENTITY,
-				    entityName,
-				    publicId,
-				    systemId);
-      if (resolved != null) {
-	return resolved;
-      }
-    }
-
-    // If there's a ENTITY entry in this catalog, use it
-    boolean over = default_override;
-    Enumeration en = catalogEntries.elements();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-      if (e.getEntryType() == OVERRIDE) {
-	over = e.getEntryArg(0).equalsIgnoreCase("YES");
-	continue;
-      }
-
-      if (e.getEntryType() == ENTITY
-	  && e.getEntryArg(0).equals(entityName)) {
-	if (over || systemId == null) {
-	  return e.getEntryArg(1);
-	}
-      }
-    }
-
-    // Otherwise, look in the subordinate catalogs
-    return resolveSubordinateCatalogs(ENTITY,
-				      entityName,
-				      publicId,
-				      systemId);
-  }
-
-  /**
-   * Return the applicable NOTATION system identifier.
-   *
-   * @param notationName The name of the notation for which
-   * a doctype is required.
-   * @param publicId The nominal public identifier for the notation
-   * (as provided in the source document).
-   * @param systemId The nominal system identifier for the notation
-   * (as provided in the source document).
-   *
-   * @return The system identifier to use for the notation.
-   *
-   * @throws MalformedURLException The formal system identifier of a
-   * subordinate catalog cannot be turned into a valid URL.
-   * @throws IOException Error reading subordinate catalog file.
-   */
-  public String resolveNotation(String notationName,
-				String publicId,
-				String systemId)
-    throws MalformedURLException, IOException {
-    String resolved = null;
-
-    catalogManager.debug.message(3, "resolveNotation("
-		  +notationName+","+publicId+","+systemId+")");
-
-    systemId = normalizeURI(systemId);
-
-    if (publicId != null && publicId.startsWith("urn:publicid:")) {
-      publicId = PublicId.decodeURN(publicId);
-    }
-
-    if (systemId != null && systemId.startsWith("urn:publicid:")) {
-      systemId = PublicId.decodeURN(systemId);
-      if (publicId != null && !publicId.equals(systemId)) {
-	catalogManager.debug.message(1, "urn:publicid: system identifier differs from \
                public identifier; using public identifier");
-	systemId = null;
-      } else {
-	publicId = systemId;
-	systemId = null;
-      }
-    }
-
-    if (systemId != null) {
-      // If there's a SYSTEM entry in this catalog, use it
-      resolved = resolveLocalSystem(systemId);
-      if (resolved != null) {
-	return resolved;
-      }
-    }
-
-    if (publicId != null) {
-      // If there's a PUBLIC entry in this catalog, use it
-      resolved = resolveLocalPublic(NOTATION,
-				    notationName,
-				    publicId,
-				    systemId);
-      if (resolved != null) {
-	return resolved;
-      }
-    }
-
-    // If there's a NOTATION entry in this catalog, use it
-    boolean over = default_override;
-    Enumeration en = catalogEntries.elements();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-      if (e.getEntryType() == OVERRIDE) {
-	over = e.getEntryArg(0).equalsIgnoreCase("YES");
-	continue;
-      }
-
-      if (e.getEntryType() == NOTATION
-	  && e.getEntryArg(0).equals(notationName)) {
-	if (over || systemId == null) {
-	  return e.getEntryArg(1);
-	}
-      }
-    }
-
-    // Otherwise, look in the subordinate catalogs
-    return resolveSubordinateCatalogs(NOTATION,
-				      notationName,
-				      publicId,
-				      systemId);
-  }
-
-  /**
-   * Return the applicable PUBLIC or SYSTEM identifier.
-   *
-   * <p>This method searches the Catalog and returns the system
-   * identifier specified for the given system or
-   * public identifiers. If
-   * no appropriate PUBLIC or SYSTEM entry is found in the Catalog,
-   * null is returned.</p>
-   *
-   * @param publicId The public identifier to locate in the catalog.
-   * Public identifiers are normalized before comparison.
-   * @param systemId The nominal system identifier for the entity
-   * in question (as provided in the source document).
-   *
-   * @throws MalformedURLException The formal system identifier of a
-   * subordinate catalog cannot be turned into a valid URL.
-   * @throws IOException Error reading subordinate catalog file.
-   *
-   * @return The system identifier to use.
-   * Note that the nominal system identifier is not returned if a
-   * match is not found in the catalog, instead null is returned
-   * to indicate that no match was found.
-   */
-  public String resolvePublic(String publicId, String systemId) 
-    throws MalformedURLException, IOException {
-
-    catalogManager.debug.message(3, "resolvePublic("+publicId+","+systemId+")");
-
-    systemId = normalizeURI(systemId);
-
-    if (publicId != null && publicId.startsWith("urn:publicid:")) {
-      publicId = PublicId.decodeURN(publicId);
-    }
-
-    if (systemId != null && systemId.startsWith("urn:publicid:")) {
-      systemId = PublicId.decodeURN(systemId);
-      if (publicId != null && !publicId.equals(systemId)) {
-	catalogManager.debug.message(1, "urn:publicid: system identifier differs from \
                public identifier; using public identifier");
-	systemId = null;
-      } else {
-	publicId = systemId;
-	systemId = null;
-      }
-    }
-
-    // If there's a SYSTEM entry in this catalog, use it
-    if (systemId != null) {
-      String resolved = resolveLocalSystem(systemId);
-      if (resolved != null) {
-	return resolved;
-      }
-    }
-
-    // If there's a PUBLIC entry in this catalog, use it
-    String resolved = resolveLocalPublic(PUBLIC,
-					 null,
-					 publicId,
-					 systemId);
-    if (resolved != null) {
-      return resolved;
-    }
-
-    // Otherwise, look in the subordinate catalogs
-    return resolveSubordinateCatalogs(PUBLIC,
-				      null,
-				      publicId,
-				      systemId);
-  }
-
-  /**
-   * Return the applicable PUBLIC or SYSTEM identifier.
-   *
-   * <p>This method searches the Catalog and returns the system
-   * identifier specified for the given system or public identifiers.
-   * If no appropriate PUBLIC or SYSTEM entry is found in the Catalog,
-   * delegated Catalogs are interrogated.</p>
-   *
-   * <p>There are four possible cases:</p>
-   *
-   * <ul>
-   * <li>If the system identifier provided matches a SYSTEM entry
-   * in the current catalog, the SYSTEM entry is returned.
-   * <li>If the system identifier is not null, the PUBLIC entries
-   * that were encountered when OVERRIDE YES was in effect are
-   * interrogated and the first matching entry is returned.</li>
-   * <li>If the system identifier is null, then all of the PUBLIC
-   * entries are interrogated and the first matching entry
-   * is returned. This may not be the same as the preceding case, if
-   * some PUBLIC entries are encountered when OVERRIDE NO is in effect. In
-   * XML, the only place where a public identifier may occur without
-   * a system identifier is in a notation declaration.</li>
-   * <li>Finally, if the public identifier matches one of the partial
-   * public identifiers specified in a DELEGATE* entry in
-   * the Catalog, the delegated catalog is interrogated. The first
-   * time that the delegated catalog is required, it will be
-   * retrieved and parsed. It is subsequently cached.
-   * </li>
-   * </ul>
-   *
-   * @param entityType The CatalogEntry type for which this query is
-   * being conducted. This is necessary in order to do the approprate
-   * query on a delegated catalog.
-   * @param entityName The name of the entity being searched for, if
-   * appropriate.
-   * @param publicId The public identifier of the entity in question.
-   * @param systemId The nominal system identifier for the entity
-   * in question (as provided in the source document).
-   *
-   * @throws MalformedURLException The formal system identifier of a
-   * delegated catalog cannot be turned into a valid URL.
-   * @throws IOException Error reading delegated catalog file.
-   *
-   * @return The system identifier to use.
-   * Note that the nominal system identifier is not returned if a
-   * match is not found in the catalog, instead null is returned
-   * to indicate that no match was found.
-   */
-  protected synchronized String resolveLocalPublic(int entityType,
-						   String entityName,
-						   String publicId,
-						   String systemId)
-    throws MalformedURLException, IOException {
-
-    // Always normalize the public identifier before attempting a match
-    publicId = PublicId.normalize(publicId);
-
-    // If there's a SYSTEM entry in this catalog, use it
-    if (systemId != null) {
-      String resolved = resolveLocalSystem(systemId);
-      if (resolved != null) {
-	return resolved;
-      }
-    }
-
-    // If there's a PUBLIC entry in this catalog, use it
-    boolean over = default_override;
-    Enumeration en = catalogEntries.elements();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-      if (e.getEntryType() == OVERRIDE) {
-	over = e.getEntryArg(0).equalsIgnoreCase("YES");
-	continue;
-      }
-
-      if (e.getEntryType() == PUBLIC
-	  && e.getEntryArg(0).equals(publicId)) {
-	if (over || systemId == null) {
-	  return e.getEntryArg(1);
-	}
-      }
-    }
-
-    // If there's a DELEGATE_PUBLIC entry in this catalog, use it
-    over = default_override;
-    en = catalogEntries.elements();
-    Vector delCats = new Vector();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-      if (e.getEntryType() == OVERRIDE) {
-	over = e.getEntryArg(0).equalsIgnoreCase("YES");
-	continue;
-      }
-
-      if (e.getEntryType() == DELEGATE_PUBLIC
-	  && (over || systemId == null)) {
-	String p = (String) e.getEntryArg(0);
-	if (p.length() <= publicId.length()
-	    && p.equals(publicId.substring(0, p.length()))) {
-	  // delegate this match to the other catalog
-
-	  delCats.addElement(e.getEntryArg(1));
-	}
-      }
-    }
-
-    if (delCats.size() > 0) {
-      Enumeration enCats = delCats.elements();
-
-      if (catalogManager.debug.getDebug() > 1) {
-	catalogManager.debug.message(2, "Switching to delegated catalog(s):");
-	while (enCats.hasMoreElements()) {
-	  String delegatedCatalog = (String) enCats.nextElement();
-	  catalogManager.debug.message(2, "\t" + delegatedCatalog);
-	}
-      }
-
-      Catalog dcat = newCatalog();
-
-      enCats = delCats.elements();
-      while (enCats.hasMoreElements()) {
-	String delegatedCatalog = (String) enCats.nextElement();
-	dcat.parseCatalog(delegatedCatalog);
-      }
-
-      return dcat.resolvePublic(publicId, null);
-    }
-
-    // Nada!
-    return null;
-  }
-
-  /**
-   * Return the applicable SYSTEM system identifier.
-   *
-   * <p>If a SYSTEM entry exists in the Catalog
-   * for the system ID specified, return the mapped value.</p>
-   *
-   * <p>On Windows-based operating systems, the comparison between
-   * the system identifier provided and the SYSTEM entries in the
-   * Catalog is case-insensitive.</p>
-   *
-   * @param systemId The system ID to locate in the catalog.
-   *
-   * @return The resolved system identifier.
-   *
-   * @throws MalformedURLException The formal system identifier of a
-   * subordinate catalog cannot be turned into a valid URL.
-   * @throws IOException Error reading subordinate catalog file.
-   */
-  public String resolveSystem(String systemId)
-    throws MalformedURLException, IOException {
-
-    catalogManager.debug.message(3, "resolveSystem("+systemId+")");
-
-    systemId = normalizeURI(systemId);
-
-    if (systemId != null && systemId.startsWith("urn:publicid:")) {
-      systemId = PublicId.decodeURN(systemId);
-      return resolvePublic(systemId, null);
-    }
-
-    // If there's a SYSTEM entry in this catalog, use it
-    if (systemId != null) {
-      String resolved = resolveLocalSystem(systemId);
-      if (resolved != null) {
-	return resolved;
-      }
-    }
-
-    // Otherwise, look in the subordinate catalogs
-    return resolveSubordinateCatalogs(SYSTEM,
-				      null,
-				      null,
-				      systemId);
-  }
-
-  /**
-   * Return the applicable SYSTEM system identifier in this
-   * catalog.
-   *
-   * <p>If a SYSTEM entry exists in the catalog file
-   * for the system ID specified, return the mapped value.</p>
-   *
-   * @param systemId The system ID to locate in the catalog
-   *
-   * @return The mapped system identifier or null
-   */
-  protected String resolveLocalSystem(String systemId)
-    throws MalformedURLException, IOException {
-
-    String osname = SecuritySupport.getSystemProperty("os.name");
-    boolean windows = (osname.indexOf("Windows") >= 0);
-    Enumeration en = catalogEntries.elements();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-      if (e.getEntryType() == SYSTEM
-	  && (e.getEntryArg(0).equals(systemId)
-	      || (windows
-		  && e.getEntryArg(0).equalsIgnoreCase(systemId)))) {
-	return e.getEntryArg(1);
-      }
-    }
-
-    // If there's a REWRITE_SYSTEM entry in this catalog, use it
-    en = catalogEntries.elements();
-    String startString = null;
-    String prefix = null;
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-
-      if (e.getEntryType() == REWRITE_SYSTEM) {
-	String p = (String) e.getEntryArg(0);
-	if (p.length() <= systemId.length()
-	    && p.equals(systemId.substring(0, p.length()))) {
-	  // Is this the longest prefix?
-	  if (startString == null
-	      || p.length() > startString.length()) {
-	    startString = p;
-	    prefix = e.getEntryArg(1);
-	  }
-	}
-      }
-    }
-
-    if (prefix != null) {
-      // return the systemId with the new prefix
-      return prefix + systemId.substring(startString.length());
-    }
-
-    // If there's a SYSTEM_SUFFIX entry in this catalog, use it
-    en = catalogEntries.elements();
-    String suffixString = null;
-    String suffixURI = null;
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-
-      if (e.getEntryType() == SYSTEM_SUFFIX) {
-	String p = (String) e.getEntryArg(0);
-	if (p.length() <= systemId.length()
-	    && systemId.endsWith(p)) {
-	  // Is this the longest prefix?
-	  if (suffixString == null
-	      || p.length() > suffixString.length()) {
-	    suffixString = p;
-	    suffixURI = e.getEntryArg(1);
-	  }
-	}
-      }
-    }
-
-    if (suffixURI != null) {
-      // return the systemId for the suffix
-      return suffixURI;
-    }
-
-    // If there's a DELEGATE_SYSTEM entry in this catalog, use it
-    en = catalogEntries.elements();
-    Vector delCats = new Vector();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-
-      if (e.getEntryType() == DELEGATE_SYSTEM) {
-	String p = (String) e.getEntryArg(0);
-	if (p.length() <= systemId.length()
-	    && p.equals(systemId.substring(0, p.length()))) {
-	  // delegate this match to the other catalog
-
-	  delCats.addElement(e.getEntryArg(1));
-	}
-      }
-    }
-
-    if (delCats.size() > 0) {
-      Enumeration enCats = delCats.elements();
-
-      if (catalogManager.debug.getDebug() > 1) {
-	catalogManager.debug.message(2, "Switching to delegated catalog(s):");
-	while (enCats.hasMoreElements()) {
-	  String delegatedCatalog = (String) enCats.nextElement();
-	  catalogManager.debug.message(2, "\t" + delegatedCatalog);
-	}
-      }
-
-      Catalog dcat = newCatalog();
-
-      enCats = delCats.elements();
-      while (enCats.hasMoreElements()) {
-	String delegatedCatalog = (String) enCats.nextElement();
-	dcat.parseCatalog(delegatedCatalog);
-      }
-
-      return dcat.resolveSystem(systemId);
-    }
-
-    return null;
-  }
-
-  /**
-   * Return the applicable URI.
-   *
-   * <p>If a URI entry exists in the Catalog
-   * for the URI specified, return the mapped value.</p>
-   *
-   * <p>URI comparison is case sensitive.</p>
-   *
-   * @param uri The URI to locate in the catalog.
-   *
-   * @return The resolved URI.
-   *
-   * @throws MalformedURLException The system identifier of a
-   * subordinate catalog cannot be turned into a valid URL.
-   * @throws IOException Error reading subordinate catalog file.
-   */
-  public String resolveURI(String uri)
-    throws MalformedURLException, IOException {
-
-    catalogManager.debug.message(3, "resolveURI("+uri+")");
-
-    uri = normalizeURI(uri);
-
-    if (uri != null && uri.startsWith("urn:publicid:")) {
-      uri = PublicId.decodeURN(uri);
-      return resolvePublic(uri, null);
-    }
-
-    // If there's a URI entry in this catalog, use it
-    if (uri != null) {
-      String resolved = resolveLocalURI(uri);
-      if (resolved != null) {
-	return resolved;
-      }
-    }
-
-    // Otherwise, look in the subordinate catalogs
-    return resolveSubordinateCatalogs(URI,
-				      null,
-				      null,
-				      uri);
-  }
-
-  /**
-   * Return the applicable URI in this catalog.
-   *
-   * <p>If a URI entry exists in the catalog file
-   * for the URI specified, return the mapped value.</p>
-   *
-   * @param uri The URI to locate in the catalog
-   *
-   * @return The mapped URI or null
-   */
-  protected String resolveLocalURI(String uri)
-    throws MalformedURLException, IOException {
-    Enumeration en = catalogEntries.elements();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-      if (e.getEntryType() == URI
-	  && (e.getEntryArg(0).equals(uri))) {
-	return e.getEntryArg(1);
-      }
-    }
-
-    // If there's a REWRITE_URI entry in this catalog, use it
-    en = catalogEntries.elements();
-    String startString = null;
-    String prefix = null;
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-
-      if (e.getEntryType() == REWRITE_URI) {
-	String p = (String) e.getEntryArg(0);
-	if (p.length() <= uri.length()
-	    && p.equals(uri.substring(0, p.length()))) {
-	  // Is this the longest prefix?
-	  if (startString == null
-	      || p.length() > startString.length()) {
-	    startString = p;
-	    prefix = e.getEntryArg(1);
-	  }
-	}
-      }
-    }
-
-    if (prefix != null) {
-      // return the uri with the new prefix
-      return prefix + uri.substring(startString.length());
-    }
-
-    // If there's a URI_SUFFIX entry in this catalog, use it
-    en = catalogEntries.elements();
-    String suffixString = null;
-    String suffixURI = null;
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-
-      if (e.getEntryType() == URI_SUFFIX) {
-	String p = (String) e.getEntryArg(0);
-	if (p.length() <= uri.length()
-	    && uri.endsWith(p)) {
-	  // Is this the longest prefix?
-	  if (suffixString == null
-	      || p.length() > suffixString.length()) {
-	    suffixString = p;
-	    suffixURI = e.getEntryArg(1);
-	  }
-	}
-      }
-    }
-
-    if (suffixURI != null) {
-      // return the uri for the suffix
-      return suffixURI;
-    }
-
-    // If there's a DELEGATE_URI entry in this catalog, use it
-    en = catalogEntries.elements();
-    Vector delCats = new Vector();
-    while (en.hasMoreElements()) {
-      CatalogEntry e = (CatalogEntry) en.nextElement();
-
-      if (e.getEntryType() == DELEGATE_URI) {
-	String p = (String) e.getEntryArg(0);
-	if (p.length() <= uri.length()
-	    && p.equals(uri.substring(0, p.length()))) {
-	  // delegate this match to the other catalog
-
-	  delCats.addElement(e.getEntryArg(1));
-	}
-      }
-    }
-
-    if (delCats.size() > 0) {
-      Enumeration enCats = delCats.elements();
-
-      if (catalogManager.debug.getDebug() > 1) {
-	catalogManager.debug.message(2, "Switching to delegated catalog(s):");
-	while (enCats.hasMoreElements()) {
-	  String delegatedCatalog = (String) enCats.nextElement();
-	  catalogManager.debug.message(2, "\t" + delegatedCatalog);
-	}
-      }
-
-      Catalog dcat = newCatalog();
-
-      enCats = delCats.elements();
-      while (enCats.hasMoreElements()) {
-	String delegatedCatalog = (String) enCats.nextElement();
-	dcat.parseCatalog(delegatedCatalog);
-      }
-
-      return dcat.resolveURI(uri);
-    }
-
-    return null;
-  }
-
-  /**
-   * Search the subordinate catalogs, in order, looking for a match.
-   *
-   * <p>This method searches the Catalog and returns the system
-   * identifier specified for the given entity type with the given
-   * name, public, and system identifiers. In some contexts, these
-   * may be null.</p>
-   *
-   * @param entityType The CatalogEntry type for which this query is
-   * being conducted. This is necessary in order to do the approprate
-   * query on a subordinate catalog.
-   * @param entityName The name of the entity being searched for, if
-   * appropriate.
-   * @param publicId The public identifier of the entity in question
-   * (as provided in the source document).
-   * @param systemId The nominal system identifier for the entity
-   * in question (as provided in the source document). This parameter is
-   * overloaded for the URI entry type.
-   *
-   * @throws MalformedURLException The formal system identifier of a
-   * delegated catalog cannot be turned into a valid URL.
-   * @throws IOException Error reading delegated catalog file.
-   *
-   * @return The system identifier to use.
-   * Note that the nominal system identifier is not returned if a
-   * match is not found in the catalog, instead null is returned
-   * to indicate that no match was found.
-   */
-  protected synchronized String resolveSubordinateCatalogs(int entityType,
-							   String entityName,
-							   String publicId,
-							   String systemId)
-    throws MalformedURLException, IOException {
-
-    for (int catPos = 0; catPos < catalogs.size(); catPos++) {
-      Catalog c = null;
-
-      try {
-	c = (Catalog) catalogs.elementAt(catPos);
-      } catch (ClassCastException e) {
-	String catfile = (String) catalogs.elementAt(catPos);
-	c = newCatalog();
-
-	try {

[... 1531 lines stripped ...]


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xerces.apache.org
For additional commands, e-mail: commits-help@xerces.apache.org


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic