/**
   * Returns the URI mapping in the catalog for the given URI reference or <code>null</code> if no
   * mapping exists. URI comparison is case sensitive. If the URI reference is an URN in the <code>
   * publicid</code> namespace it is converted into a public identifier by URN "unwrapping" as
   * specified in the XML Catalogs specification and then resolution is performed following the
   * semantics of external identifier resolution.
   *
   * @param uri the URI to locate in the catalog
   * @return the mapped URI or <code>null</code> if no mapping was found in the catalog
   * @throws IOException if an i/o error occurred while reading the catalog
   */
  public final synchronized String resolveURI(String uri) throws IOException {

    if (fCatalogsChanged) {
      parseCatalogs();
      fCatalogsChanged = false;
    }
    return (fCatalog != null) ? fCatalog.resolveURI(uri) : null;
  }
  /**
   * Returns the URI mapping in the catalog for the given external identifier or <code>null</code>
   * if no mapping exists. If the system identifier is an URN in the <code>publicid</code> namespace
   * it is converted into a public identifier by URN "unwrapping" as specified in the XML Catalogs
   * specification.
   *
   * @param systemId the system identifier to locate in the catalog
   * @return the mapped URI or <code>null</code> if no mapping was found in the catalog
   * @throws IOException if an i/o error occurred while reading the catalog
   */
  public final synchronized String resolveSystem(String systemId) throws IOException {

    if (fCatalogsChanged) {
      parseCatalogs();
      fCatalogsChanged = false;
    }
    return (fCatalog != null) ? fCatalog.resolveSystem(systemId) : null;
  }
  /** Attaches the reader to the catalog. */
  private void attachReaderToCatalog(Catalog catalog) {

    SAXParserFactory spf = new SAXParserFactoryImpl();
    spf.setNamespaceAware(true);
    spf.setValidating(false);

    SAXCatalogReader saxReader = new SAXCatalogReader(spf);
    saxReader.setCatalogParser(
        OASISXMLCatalogReader.namespaceName,
        "catalog",
        "com.sun.org.apache.xml.internal.resolver.readers.OASISXMLCatalogReader");
    catalog.addReader("application/xml", saxReader);
  }
 /**
  * Instruct the <code>Catalog</code> to parse each of the catalogs in the list. Only the first
  * catalog will actually be parsed immediately. The others will be queued and read if they are
  * needed later.
  */
 private void parseCatalogs() throws IOException {
   if (fCatalogsList != null) {
     fCatalog = new Catalog(fResolverCatalogManager);
     attachReaderToCatalog(fCatalog);
     for (int i = 0; i < fCatalogsList.length; ++i) {
       String catalog = fCatalogsList[i];
       if (catalog != null && catalog.length() > 0) {
         fCatalog.parseCatalog(catalog);
       }
     }
   } else {
     fCatalog = null;
   }
 }
  /**
   * Read a catalog from an input stream.
   *
   * <p>This class reads a catalog from an input stream:
   *
   * <ul>
   *   <li>Based on the QName of the root element, it determines which parser to instantiate for
   *       this catalog.
   *   <li>It constructs a DOM Document from the catalog and
   *   <li>For each child of the root node, it calls the parser's parseCatalogEntry method. This
   *       method is expected to make appropriate calls back into the catalog to add entries for the
   *       entries in the catalog. It is free to do this in whatever manner is appropriate (perhaps
   *       using just the node passed in, perhaps wandering arbitrarily throughout the tree).
   * </ul>
   *
   * @param catalog The catalog for which this reader is called.
   * @param is The input stream that is to be read.
   * @throws IOException if the URL cannot be read.
   * @throws UnknownCatalogFormatException if the catalog format is not recognized.
   * @throws UnparseableCatalogException if the catalog cannot be parsed. (For example, if it is
   *     supposed to be XML and isn't well-formed or if the parser class cannot be instantiated.)
   */
  public void readCatalog(Catalog catalog, InputStream is) throws IOException, CatalogException {

    DocumentBuilderFactory factory = null;
    DocumentBuilder builder = null;

    factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(false);
    factory.setValidating(false);
    try {
      builder = factory.newDocumentBuilder();
    } catch (ParserConfigurationException pce) {
      throw new CatalogException(CatalogException.UNPARSEABLE);
    }

    Document doc = null;

    try {
      doc = builder.parse(is);
    } catch (SAXException se) {
      throw new CatalogException(CatalogException.UNKNOWN_FORMAT);
    }

    Element root = doc.getDocumentElement();

    String namespaceURI = Namespaces.getNamespaceURI(root);
    String localName = Namespaces.getLocalName(root);

    String domParserClass = getCatalogParser(namespaceURI, localName);

    if (domParserClass == null) {
      if (namespaceURI == null) {
        catalog.getCatalogManager().debug.message(1, "No Catalog parser for " + localName);
      } else {
        catalog
            .getCatalogManager()
            .debug
            .message(1, "No Catalog parser for " + "{" + namespaceURI + "}" + localName);
      }
      return;
    }

    DOMCatalogParser domParser = null;

    try {
      domParser = (DOMCatalogParser) Class.forName(domParserClass).newInstance();
    } catch (ClassNotFoundException cnfe) {
      catalog
          .getCatalogManager()
          .debug
          .message(1, "Cannot load XML Catalog Parser class", domParserClass);
      throw new CatalogException(CatalogException.UNPARSEABLE);
    } catch (InstantiationException ie) {
      catalog
          .getCatalogManager()
          .debug
          .message(1, "Cannot instantiate XML Catalog Parser class", domParserClass);
      throw new CatalogException(CatalogException.UNPARSEABLE);
    } catch (IllegalAccessException iae) {
      catalog
          .getCatalogManager()
          .debug
          .message(1, "Cannot access XML Catalog Parser class", domParserClass);
      throw new CatalogException(CatalogException.UNPARSEABLE);
    } catch (ClassCastException cce) {
      catalog
          .getCatalogManager()
          .debug
          .message(1, "Cannot cast XML Catalog Parser class", domParserClass);
      throw new CatalogException(CatalogException.UNPARSEABLE);
    }

    Node node = root.getFirstChild();
    while (node != null) {
      domParser.parseCatalogEntry(catalog, node);
      node = node.getNextSibling();
    }
  }