/**
   * Create a new <code>ColladaRoot</code> for a {@link URL}.
   *
   * @param docSource the URL of the document.
   * @throws IllegalArgumentException if the document source is null.
   * @throws IOException if an error occurs while reading the Collada document.
   */
  public ColladaRoot(URL docSource) throws IOException {
    super(ColladaConstants.COLLADA_NAMESPACE);

    if (docSource == null) {
      String message = Logging.getMessage("nullValue.DocumentSourceIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    URLConnection conn = docSource.openConnection();
    this.colladaDoc = new ColladaInputStream(conn.getInputStream(), WWIO.makeURI(docSource));

    this.initialize();
  }
  /**
   * Open and parse the specified file expressed as a file: URL..
   *
   * @param url the URL of the file to open, expressed as a URL with a scheme of "file".
   * @param linkBase the original address of the document if the file is a retrieved and cached
   *     file.
   * @return A {@code ColladaRoot} representing the file's COLLADA contents.
   * @throws IOException if an I/O error occurs during opening and parsing.
   * @throws XMLStreamException if a server parsing error is encountered.
   */
  protected ColladaRoot parseCachedColladaFile(URL url, String linkBase)
      throws IOException, XMLStreamException {
    ColladaDoc colladaDoc;

    InputStream refStream = url.openStream();

    colladaDoc = new ColladaInputStream(refStream, WWIO.makeURI(linkBase));

    try {
      ColladaRoot refRoot = new ColladaRoot(colladaDoc);
      refRoot.parse(); // also closes the URL's stream
      return refRoot;
    } catch (XMLStreamException e) {
      refStream.close(); // parsing failed, so explicitly close the stream
      throw e;
    }
  }