/**
   * Implements javax.xml.transform.sax.TransformerHandler.setResult() Enables the user of the
   * TransformerHandler to set the to set the Result for the transformation.
   *
   * @param result A Result instance, should not be null
   * @throws IllegalArgumentException if result is invalid for some reason
   */
  public void setResult(Result result) throws IllegalArgumentException {
    _result = result;

    if (null == result) {
      ErrorMsg err = new ErrorMsg(ErrorMsg.ER_RESULT_NULL);
      throw new IllegalArgumentException(err.toString()); // "result should not be null");
    }

    if (_isIdentity) {
      try {
        // Connect this object with output system directly
        SerializationHandler outputHandler = _transformer.getOutputHandler(result);
        _transformer.transferOutputProperties(outputHandler);

        _handler = outputHandler;
        _lexHandler = outputHandler;
      } catch (TransformerException e) {
        _result = null;
      }
    } else if (_done) {
      // Run the transformation now, if not already done
      try {
        _transformer.setDOM(_dom);
        _transformer.transform(null, _result);
      } catch (TransformerException e) {
        // What the hell are we supposed to do with this???
        throw new IllegalArgumentException(e.getMessage());
      }
    }
  }
  /**
   * Convenience class to transform a node.
   *
   * @param xsl path name to the xsl file.
   * @param xml dom source document.
   * @param out output stream destination.
   */
  public void transform(String xsl, Node xml, OutputStream out) throws Exception {
    TransformerImpl transformer;

    transformer = (TransformerImpl) newTemplates(xsl).newTransformer();

    transformer.transform(xml, out);
  }
  /** Cosntructor - pass in reference to a TransformerImpl object */
  public TransformerHandlerImpl(TransformerImpl transformer) {
    // Save the reference to the transformer
    _transformer = transformer;

    if (transformer.isIdentity()) {
      // Set initial handler to the empty handler
      _handler = new DefaultHandler();
      _isIdentity = true;
    } else {
      // Get a reference to the translet wrapped inside the transformer
      _translet = _transformer.getTranslet();
    }
  }
  /**
   * Implements JAXP's Templates.newTransformer()
   *
   * @throws TransformerConfigurationException
   */
  public synchronized Transformer newTransformer() throws TransformerConfigurationException {
    TransformerImpl transformer;

    transformer =
        new TransformerImpl(getTransletInstance(), _outputProperties, _indentNumber, _tfactory);

    if (_uriResolver != null) {
      transformer.setURIResolver(_uriResolver);
    }

    if (_tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) {
      transformer.setSecureProcessing(true);
    }
    return transformer;
  }
  /**
   * Implements org.xml.sax.ContentHandler.endDocument() Receive notification of the end of a
   * document.
   */
  public void endDocument() throws SAXException {
    // Signal to the DOMBuilder that the document is complete
    _handler.endDocument();

    if (!_isIdentity) {
      // Run the transformation now if we have a reference to a Result object
      if (_result != null) {
        try {
          _transformer.setDOM(_dom);
          _transformer.transform(null, _result);
        } catch (TransformerException e) {
          throw new SAXException(e);
        }
      }
      // Signal that the internal DOM is built (see 'setResult()').
      _done = true;

      // Set this DOM as the transformer's DOM
      _transformer.setDOM(_dom);
    }
    if (_isIdentity && _result instanceof DOMResult) {
      ((DOMResult) _result).setNode(_transformer.getTransletOutputHandlerFactory().getNode());
    }
  }
  /**
   * Implements org.xml.sax.ContentHandler.startDocument() Receive notification of the beginning of
   * a document.
   */
  public void startDocument() throws SAXException {
    // Make sure setResult() was called before the first SAX event
    if (_result == null) {
      ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_SET_RESULT_ERR);
      throw new SAXException(err.toString());
    }

    if (!_isIdentity) {
      boolean hasIdCall = (_translet != null) ? _translet.hasIdCall() : false;
      XSLTCDTMManager dtmManager = null;

      // Create an internal DOM (not W3C) and get SAX2 input handler
      try {
        dtmManager =
            (XSLTCDTMManager)
                _transformer.getTransformerFactory().getDTMManagerClass().newInstance();
      } catch (Exception e) {
        throw new SAXException(e);
      }

      DTMWSFilter wsFilter;
      if (_translet != null && _translet instanceof StripFilter) {
        wsFilter = new DOMWSFilter(_translet);
      } else {
        wsFilter = null;
      }

      // Construct the DTM using the SAX events that come through
      _dom = (SAXImpl) dtmManager.getDTM(null, false, wsFilter, true, false, hasIdCall);

      _handler = _dom.getBuilder();
      _lexHandler = (LexicalHandler) _handler;
      _dtdHandler = (DTDHandler) _handler;
      _declHandler = (DeclHandler) _handler;

      // Set document URI
      _dom.setDocumentURI(_systemId);

      if (_locator != null) {
        _handler.setDocumentLocator(_locator);
      }
    }

    // Proxy call
    _handler.startDocument();
  }
  /**
   * Convenience class to transform a node.
   *
   * @param xsl DOM containing the parsed xsl.
   * @param xml DOM document node.
   * @param out output stream destination.
   */
  public void transform(Document xsl, Node xml, OutputStream out) throws Exception {
    TransformerImpl transformer = (TransformerImpl) newTransformer(xsl);

    transformer.transform(xml, out);
  }