All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.xalan.transformer.TransformerIdentityImpl Maven / Gradle / Ivy

There is a newer version: 1.2.9
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: TransformerIdentityImpl.java 575747 2007-09-14 16:28:37Z kcormier $
 */
package org.apache.xalan.transformer;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Properties;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.templates.OutputProperties;
import org.apache.xml.serializer.Serializer;
import org.apache.xml.serializer.SerializerFactory;
import org.apache.xml.serializer.Method;
import org.apache.xml.utils.DOMBuilder;
import org.apache.xml.utils.XMLReaderManager;

import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.ext.LexicalHandler;

/**
 * This class implements an identity transformer for
 * {@link javax.xml.transform.sax.SAXTransformerFactory#newTransformerHandler()}
 * and {@link javax.xml.transform.TransformerFactory#newTransformer()}.  It
 * simply feeds SAX events directly to a serializer ContentHandler, if the
 * result is a stream.  If the result is a DOM, it will send the events to
 * {@link org.apache.xml.utils.DOMBuilder}.  If the result is another
 * content handler, it will simply pass the events on.
 */
public class TransformerIdentityImpl extends Transformer
        implements TransformerHandler, DeclHandler
{

  /**
   * Constructor TransformerIdentityImpl creates an identity transform.
   *
   */
  public TransformerIdentityImpl(boolean isSecureProcessing)
  {
    m_outputFormat = new OutputProperties(Method.XML);
    m_isSecureProcessing = isSecureProcessing;
  }

  /**
   * Constructor TransformerIdentityImpl creates an identity transform.
   *
   */
  public TransformerIdentityImpl()
  {
    this(false);
  }

  /**
   * 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
  {
    if(null == result)
      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_RESULT_NULL, null)); //"Result should not be null");        
    m_result = result;
  }

  /**
   * Set the base ID (URI or system ID) from where relative
   * URLs will be resolved.
   * @param systemID Base URI for the source tree.
   */
  public void setSystemId(String systemID)
  {
    m_systemID = systemID;
  }

  /**
   * Get the base ID (URI or system ID) from where relative
   * URLs will be resolved.
   * @return The systemID that was set with {@link #setSystemId}.
   */
  public String getSystemId()
  {
    return m_systemID;
  }

  /**
   * Get the Transformer associated with this handler, which
   * is needed in order to set parameters and output properties.
   *
   * @return non-null reference to the transformer.
   */
  public Transformer getTransformer()
  {
    return this;
  }

  /**
   * Reset the status of the transformer.
   */
  public void reset()
  {
    m_flushedStartDoc = false;
    m_foundFirstElement = false;
    m_outputStream = null;
    clearParameters();
    m_result = null;
    m_resultContentHandler = null;
    m_resultDeclHandler = null;
    m_resultDTDHandler = null;
    m_resultLexicalHandler = null;
    m_serializer = null;
    m_systemID = null;
    m_URIResolver = null;
    m_outputFormat = new OutputProperties(Method.XML);
  }

  /**
   * Create a result ContentHandler from a Result object, based
   * on the current OutputProperties.
   *
   * @param outputTarget Where the transform result should go,
   * should not be null.
   *
   * @return A valid ContentHandler that will create the
   * result tree when it is fed SAX events.
   *
   * @throws TransformerException
   */
  private void createResultContentHandler(Result outputTarget)
          throws TransformerException
  {

    if (outputTarget instanceof SAXResult)
    {
      SAXResult saxResult = (SAXResult) outputTarget;

      m_resultContentHandler = saxResult.getHandler();
      m_resultLexicalHandler = saxResult.getLexicalHandler();

      if (m_resultContentHandler instanceof Serializer)
      {

        // Dubious but needed, I think.
        m_serializer = (Serializer) m_resultContentHandler;
      }
    }
    else if (outputTarget instanceof DOMResult)
    {
      DOMResult domResult = (DOMResult) outputTarget;
      Node outputNode = domResult.getNode();
      Node nextSibling = domResult.getNextSibling();
      Document doc;
      short type;

      if (null != outputNode)
      {
        type = outputNode.getNodeType();
        doc = (Node.DOCUMENT_NODE == type)
              ? (Document) outputNode : outputNode.getOwnerDocument();
      }
      else
      {
        try
        {
          DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

          dbf.setNamespaceAware(true);

          if (m_isSecureProcessing)
          {
            try
            {
              dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
            }
            catch (ParserConfigurationException pce) {}
          }

          DocumentBuilder db = dbf.newDocumentBuilder();

          doc = db.newDocument();
        }
        catch (ParserConfigurationException pce)
        {
          throw new TransformerException(pce);
        }

        outputNode = doc;
        type = outputNode.getNodeType();

        ((DOMResult) outputTarget).setNode(outputNode);
      }

      DOMBuilder domBuilder =
        (Node.DOCUMENT_FRAGMENT_NODE == type)
        ? new DOMBuilder(doc, (DocumentFragment) outputNode)
        : new DOMBuilder(doc, outputNode);
      
      if (nextSibling != null)
        domBuilder.setNextSibling(nextSibling);
      
      m_resultContentHandler = domBuilder;
      m_resultLexicalHandler = domBuilder;
    }
    else if (outputTarget instanceof StreamResult)
    {
      StreamResult sresult = (StreamResult) outputTarget;

      try
      {
        Serializer serializer =
          SerializerFactory.getSerializer(m_outputFormat.getProperties());

        m_serializer = serializer;

        if (null != sresult.getWriter())
          serializer.setWriter(sresult.getWriter());
        else if (null != sresult.getOutputStream())
          serializer.setOutputStream(sresult.getOutputStream());
        else if (null != sresult.getSystemId())
        {
          String fileURL = sresult.getSystemId();

          if (fileURL.startsWith("file:///")) {
            if (fileURL.substring(8).indexOf(":") >0) {
              fileURL = fileURL.substring(8);
            } else  {
              fileURL = fileURL.substring(7);
            }
          } else if (fileURL.startsWith("file:/")) {
            if (fileURL.substring(6).indexOf(":") >0) {
              fileURL = fileURL.substring(6);
            } else {
              fileURL = fileURL.substring(5);
            }
          }

          m_outputStream = new java.io.FileOutputStream(fileURL);
          serializer.setOutputStream(m_outputStream);
        }
        else
          throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_OUTPUT_SPECIFIED, null)); //"No output specified!");

        m_resultContentHandler = serializer.asContentHandler();
      }
      catch (IOException ioe)
      {
        throw new TransformerException(ioe);
      }
    }
    else
    {
      throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_TRANSFORM_TO_RESULT_TYPE, new Object[]{outputTarget.getClass().getName()})); //"Can't transform to a Result of type "
                                    // + outputTarget.getClass().getName()
                                    // + "!");
    }

    if (m_resultContentHandler instanceof DTDHandler)
      m_resultDTDHandler = (DTDHandler) m_resultContentHandler;
    
    if (m_resultContentHandler instanceof DeclHandler)
      m_resultDeclHandler = (DeclHandler) m_resultContentHandler;

    if (m_resultContentHandler instanceof LexicalHandler)
      m_resultLexicalHandler = (LexicalHandler) m_resultContentHandler;
  }

  /**
   * Process the source tree to the output result.
   * @param source  The input for the source tree.
   *
   * @param outputTarget The output target.
   *
   * @throws TransformerException If an unrecoverable error occurs
   * during the course of the transformation.
   */
  public void transform(Source source, Result outputTarget)
          throws TransformerException
  {

    createResultContentHandler(outputTarget);
    
    /*
     * According to JAXP1.2, new SAXSource()/StreamSource()
     * should create an empty input tree, with a default root node. 
     * new DOMSource()creates an empty document using DocumentBuilder.
     * newDocument(); Use DocumentBuilder.newDocument() for all 3 situations,
     * since there is no clear spec. how to create an empty tree when
     * both SAXSource() and StreamSource() are used.
     */
    if ((source instanceof StreamSource && source.getSystemId()==null &&
       ((StreamSource)source).getInputStream()==null &&
       ((StreamSource)source).getReader()==null)||
       (source instanceof SAXSource &&
       ((SAXSource)source).getInputSource()==null &&
       ((SAXSource)source).getXMLReader()==null )||
       (source instanceof DOMSource && ((DOMSource)source).getNode()==null)){
      try {
        DocumentBuilderFactory builderF = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = builderF.newDocumentBuilder();
        String systemID = source.getSystemId();
        source = new DOMSource(builder.newDocument());

        // Copy system ID from original, empty Source to new Source
        if (systemID != null) {
          source.setSystemId(systemID);
        }
      } catch (ParserConfigurationException e){
        throw new TransformerException(e.getMessage());
      }           
    }
    
    try
    {
      if (source instanceof DOMSource)
      {
        DOMSource dsource = (DOMSource) source;
  
        m_systemID = dsource.getSystemId();
  
        Node dNode = dsource.getNode();
  
        if (null != dNode)
        {
          try
          {
            if(dNode.getNodeType() == Node.ATTRIBUTE_NODE)
              this.startDocument();
            try
            {
              if(dNode.getNodeType() == Node.ATTRIBUTE_NODE)
              {
                String data = dNode.getNodeValue();
                char[] chars = data.toCharArray();
                characters(chars, 0, chars.length);
              }
              else
              { 
                org.apache.xml.serializer.TreeWalker walker;
                walker = new org.apache.xml.serializer.TreeWalker(this, m_systemID);
                walker.traverse(dNode);
              }
            }
            finally
            {
              if(dNode.getNodeType() == Node.ATTRIBUTE_NODE)
                this.endDocument();
            }
          }
          catch (SAXException se)
          {
            throw new TransformerException(se);
          }
  
          return;
        }
        else
        {
          String messageStr = XSLMessages.createMessage(
            XSLTErrorResources.ER_ILLEGAL_DOMSOURCE_INPUT, null);
  
          throw new IllegalArgumentException(messageStr);
        }
      }
  
      InputSource xmlSource = SAXSource.sourceToInputSource(source);
  
      if (null == xmlSource)
      {
        throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_TRANSFORM_SOURCE_TYPE, new Object[]{source.getClass().getName()})); //"Can't transform a Source of type "
                                       //+ source.getClass().getName() + "!");
      }
  
      if (null != xmlSource.getSystemId())
        m_systemID = xmlSource.getSystemId();
  
      XMLReader reader = null;
      boolean managedReader = false;
  
      try
      {
        if (source instanceof SAXSource) {
          reader = ((SAXSource) source).getXMLReader();
        }
          
        if (null == reader) {
          try {
            reader = XMLReaderManager.getInstance().getXMLReader();
            managedReader = true;
          } catch (SAXException se) {
            throw new TransformerException(se);
          }
        } else {
          try {
            reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
                              true);
          } catch (org.xml.sax.SAXException se) {
            // We don't care.
          }
        }

        // Get the input content handler, which will handle the 
        // parse events and create the source tree. 
        ContentHandler inputHandler = this;
  
        reader.setContentHandler(inputHandler);
  
        if (inputHandler instanceof org.xml.sax.DTDHandler)
          reader.setDTDHandler((org.xml.sax.DTDHandler) inputHandler);
  
        try
        {
          if (inputHandler instanceof org.xml.sax.ext.LexicalHandler)
            reader.setProperty("http://xml.org/sax/properties/lexical-handler",
                               inputHandler);
  
          if (inputHandler instanceof org.xml.sax.ext.DeclHandler)
            reader.setProperty(
              "http://xml.org/sax/properties/declaration-handler",
              inputHandler);
        }
        catch (org.xml.sax.SAXException se){}
  
        try
        {
          if (inputHandler instanceof org.xml.sax.ext.LexicalHandler)
            reader.setProperty("http://xml.org/sax/handlers/LexicalHandler",
                               inputHandler);
  
          if (inputHandler instanceof org.xml.sax.ext.DeclHandler)
            reader.setProperty("http://xml.org/sax/handlers/DeclHandler",
                               inputHandler);
        }
        catch (org.xml.sax.SAXNotRecognizedException snre){}
  
        reader.parse(xmlSource);
      }
      catch (org.apache.xml.utils.WrappedRuntimeException wre)
      {
        Throwable throwable = wre.getException();
  
        while (throwable
               instanceof org.apache.xml.utils.WrappedRuntimeException)
        {
          throwable =
            ((org.apache.xml.utils.WrappedRuntimeException) throwable).getException();
        }
  
        throw new TransformerException(wre.getException());
      }
      catch (org.xml.sax.SAXException se)
      {
        throw new TransformerException(se);
      }
      catch (IOException ioe)
      {
        throw new TransformerException(ioe);
      } finally {
        if (managedReader) {
          XMLReaderManager.getInstance().releaseXMLReader(reader);
        }
      }
    }
    finally
    {
      if(null != m_outputStream)
      {
        try
        {
          m_outputStream.close();
        }
        catch(IOException ioe){}
        m_outputStream = null;
      }
    }
  }

  /**
   * Add a parameter for the transformation.
   *
   * 

Pass a qualified name as a two-part string, the namespace URI * enclosed in curly braces ({}), followed by the local name. If the * name has a null URL, the String only contain the local name. An * application can safely check for a non-null URI by testing to see if the first * character of the name is a '{' character.

*

For example, if a URI and local name were obtained from an element * defined with <xyz:foo xmlns:xyz="http://xyz.foo.com/yada/baz.html"/>, * then the qualified name would be "{http://xyz.foo.com/yada/baz.html}foo". Note that * no prefix is used.

* * @param name The name of the parameter, which may begin with a namespace URI * in curly braces ({}). * @param value The value object. This can be any valid Java object. It is * up to the processor to provide the proper object coersion or to simply * pass the object on for use in an extension. */ public void setParameter(String name, Object value) { if (value == null) { throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_SET_PARAM_VALUE, new Object[]{name})); } if (null == m_params) { m_params = new Hashtable(); } m_params.put(name, value); } /** * Get a parameter that was explicitly set with setParameter * or setParameters. * *

This method does not return a default parameter value, which * cannot be determined until the node context is evaluated during * the transformation process. * * * @param name Name of the parameter. * @return A parameter that has been set with setParameter. */ public Object getParameter(String name) { if (null == m_params) return null; return m_params.get(name); } /** * Clear all parameters set with setParameter. */ public void clearParameters() { if (null == m_params) return; m_params.clear(); } /** * Set an object that will be used to resolve URIs used in * document(). * *

If the resolver argument is null, the URIResolver value will * be cleared, and the default behavior will be used.

* * @param resolver An object that implements the URIResolver interface, * or null. */ public void setURIResolver(URIResolver resolver) { m_URIResolver = resolver; } /** * Get an object that will be used to resolve URIs used in * document(), etc. * * @return An object that implements the URIResolver interface, * or null. */ public URIResolver getURIResolver() { return m_URIResolver; } /** * Set the output properties for the transformation. These * properties will override properties set in the Templates * with xsl:output. * *

If argument to this function is null, any properties * previously set are removed, and the value will revert to the value * defined in the templates object.

* *

Pass a qualified property key name as a two-part string, the namespace URI * enclosed in curly braces ({}), followed by the local name. If the * name has a null URL, the String only contain the local name. An * application can safely check for a non-null URI by testing to see if the first * character of the name is a '{' character.

*

For example, if a URI and local name were obtained from an element * defined with <xyz:foo xmlns:xyz="http://xyz.foo.com/yada/baz.html"/>, * then the qualified name would be "{http://xyz.foo.com/yada/baz.html}foo". Note that * no prefix is used.

* * @param oformat A set of output properties that will be * used to override any of the same properties in affect * for the transformation. * * @see javax.xml.transform.OutputKeys * @see java.util.Properties * * @throws IllegalArgumentException if any of the argument keys are not * recognized and are not namespace qualified. */ public void setOutputProperties(Properties oformat) throws IllegalArgumentException { if (null != oformat) { // See if an *explicit* method was set. String method = (String) oformat.get(OutputKeys.METHOD); if (null != method) m_outputFormat = new OutputProperties(method); else m_outputFormat = new OutputProperties(); m_outputFormat.copyFrom(oformat); } else { // if oformat is null JAXP says that any props previously set are removed // and we are to revert back to those in the templates object (i.e. Stylesheet). m_outputFormat = null; } } /** * Get a copy of the output properties for the transformation. * *

The properties returned should contain properties set by the user, * and properties set by the stylesheet, and these properties * are "defaulted" by default properties specified by section 16 of the * XSL Transformations (XSLT) W3C Recommendation. The properties that * were specifically set by the user or the stylesheet should be in the base * Properties list, while the XSLT default properties that were not * specifically set should be the default Properties list. Thus, * getOutputProperties().getProperty(String key) will obtain any * property in that was set by {@link #setOutputProperty}, * {@link #setOutputProperties}, in the stylesheet, or the default * properties, while * getOutputProperties().get(String key) will only retrieve properties * that were explicitly set by {@link #setOutputProperty}, * {@link #setOutputProperties}, or in the stylesheet.

* *

Note that mutation of the Properties object returned will not * effect the properties that the transformation contains.

* *

If any of the argument keys are not recognized and are not * namespace qualified, the property will be ignored. In other words the * behaviour is not orthogonal with setOutputProperties.

* * @return A copy of the set of output properties in effect * for the next transformation. * * @see javax.xml.transform.OutputKeys * @see java.util.Properties */ public Properties getOutputProperties() { return (Properties) m_outputFormat.getProperties().clone(); } /** * Set an output property that will be in effect for the * transformation. * *

Pass a qualified property name as a two-part string, the namespace URI * enclosed in curly braces ({}), followed by the local name. If the * name has a null URL, the String only contain the local name. An * application can safely check for a non-null URI by testing to see if the first * character of the name is a '{' character.

*

For example, if a URI and local name were obtained from an element * defined with <xyz:foo xmlns:xyz="http://xyz.foo.com/yada/baz.html"/>, * then the qualified name would be "{http://xyz.foo.com/yada/baz.html}foo". Note that * no prefix is used.

* *

The Properties object that was passed to {@link #setOutputProperties} won't * be effected by calling this method.

* * @param name A non-null String that specifies an output * property name, which may be namespace qualified. * @param value The non-null string value of the output property. * * @throws IllegalArgumentException If the property is not supported, and is * not qualified with a namespace. * * @see javax.xml.transform.OutputKeys */ public void setOutputProperty(String name, String value) throws IllegalArgumentException { if (!OutputProperties.isLegalPropertyKey(name)) throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{name})); //"output property not recognized: " //+ name); m_outputFormat.setProperty(name, value); } /** * Get an output property that is in effect for the * transformation. The property specified may be a property * that was set with setOutputProperty, or it may be a * property specified in the stylesheet. * * @param name A non-null String that specifies an output * property name, which may be namespace qualified. * * @return The string value of the output property, or null * if no property was found. * * @throws IllegalArgumentException If the property is not supported. * * @see javax.xml.transform.OutputKeys */ public String getOutputProperty(String name) throws IllegalArgumentException { String value = null; OutputProperties props = m_outputFormat; value = props.getProperty(name); if (null == value) { if (!OutputProperties.isLegalPropertyKey(name)) throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{name})); //"output property not recognized: " // + name); } return value; } /** * Set the error event listener in effect for the transformation. * * @param listener The new error listener. * @throws IllegalArgumentException if listener is null. */ public void setErrorListener(ErrorListener listener) throws IllegalArgumentException { if (listener == null) throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_NULL_ERROR_HANDLER, null)); else m_errorListener = listener; } /** * Get the error event handler in effect for the transformation. * * @return The current error handler, which should never be null. */ public ErrorListener getErrorListener() { return m_errorListener; } //////////////////////////////////////////////////////////////////// // Default implementation of DTDHandler interface. //////////////////////////////////////////////////////////////////// /** * Receive notification of a notation declaration. * *

By default, do nothing. Application writers may override this * method in a subclass if they wish to keep track of the notations * declared in a document.

* * @param name The notation name. * @param publicId The notation public identifier, or null if not * available. * @param systemId The notation system identifier. * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.DTDHandler#notationDecl * * @throws SAXException */ public void notationDecl(String name, String publicId, String systemId) throws SAXException { if (null != m_resultDTDHandler) m_resultDTDHandler.notationDecl(name, publicId, systemId); } /** * Receive notification of an unparsed entity declaration. * *

By default, do nothing. Application writers may override this * method in a subclass to keep track of the unparsed entities * declared in a document.

* * @param name The entity name. * @param publicId The entity public identifier, or null if not * available. * @param systemId The entity system identifier. * @param notationName The name of the associated notation. * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.DTDHandler#unparsedEntityDecl * * @throws SAXException */ public void unparsedEntityDecl( String name, String publicId, String systemId, String notationName) throws SAXException { if (null != m_resultDTDHandler) m_resultDTDHandler.unparsedEntityDecl(name, publicId, systemId, notationName); } //////////////////////////////////////////////////////////////////// // Default implementation of ContentHandler interface. //////////////////////////////////////////////////////////////////// /** * Receive a Locator object for document events. * *

By default, do nothing. Application writers may override this * method in a subclass if they wish to store the locator for use * with other document events.

* * @param locator A locator for all SAX document events. * @see org.xml.sax.ContentHandler#setDocumentLocator * @see org.xml.sax.Locator */ public void setDocumentLocator(Locator locator) { try { if (null == m_resultContentHandler) createResultContentHandler(m_result); } catch (TransformerException te) { throw new org.apache.xml.utils.WrappedRuntimeException(te); } m_resultContentHandler.setDocumentLocator(locator); } /** * Receive notification of the beginning of the document. * *

By default, do nothing. Application writers may override this * method in a subclass to take specific actions at the beginning * of a document (such as allocating the root node of a tree or * creating an output file).

* * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#startDocument * * @throws SAXException */ public void startDocument() throws SAXException { try { if (null == m_resultContentHandler) createResultContentHandler(m_result); } catch (TransformerException te) { throw new SAXException(te.getMessage(), te); } // Reset for multiple transforms with this transformer. m_flushedStartDoc = false; m_foundFirstElement = false; } boolean m_flushedStartDoc = false; protected final void flushStartDoc() throws SAXException { if(!m_flushedStartDoc) { if (m_resultContentHandler == null) { try { createResultContentHandler(m_result); } catch(TransformerException te) { throw new SAXException(te); } } m_resultContentHandler.startDocument(); m_flushedStartDoc = true; } } /** * Receive notification of the end of the document. * *

By default, do nothing. Application writers may override this * method in a subclass to take specific actions at the end * of a document (such as finalising a tree or closing an output * file).

* * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#endDocument * * @throws SAXException */ public void endDocument() throws SAXException { flushStartDoc(); m_resultContentHandler.endDocument(); } /** * Receive notification of the start of a Namespace mapping. * *

By default, do nothing. Application writers may override this * method in a subclass to take specific actions at the start of * each Namespace prefix scope (such as storing the prefix mapping).

* * @param prefix The Namespace prefix being declared. * @param uri The Namespace URI mapped to the prefix. * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#startPrefixMapping * * @throws SAXException */ public void startPrefixMapping(String prefix, String uri) throws SAXException { flushStartDoc(); m_resultContentHandler.startPrefixMapping(prefix, uri); } /** * Receive notification of the end of a Namespace mapping. * *

By default, do nothing. Application writers may override this * method in a subclass to take specific actions at the end of * each prefix mapping.

* * @param prefix The Namespace prefix being declared. * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#endPrefixMapping * * @throws SAXException */ public void endPrefixMapping(String prefix) throws SAXException { flushStartDoc(); m_resultContentHandler.endPrefixMapping(prefix); } /** * Receive notification of the start of an element. * *

By default, do nothing. Application writers may override this * method in a subclass to take specific actions at the start of * each element (such as allocating a new tree node or writing * output to a file).

* * @param uri The Namespace URI, or the empty string if the * element has no Namespace URI or if Namespace * processing is not being performed. * @param localName The local name (without prefix), or the * empty string if Namespace processing is not being * performed. * @param qName The qualified name (with prefix), or the * empty string if qualified names are not available. * @param attributes The specified or defaulted attributes. * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#startElement * * @throws SAXException */ public void startElement( String uri, String localName, String qName, Attributes attributes) throws SAXException { if (!m_foundFirstElement && null != m_serializer) { m_foundFirstElement = true; Serializer newSerializer; try { newSerializer = SerializerSwitcher.switchSerializerIfHTML(uri, localName, m_outputFormat.getProperties(), m_serializer); } catch (TransformerException te) { throw new SAXException(te); } if (newSerializer != m_serializer) { try { m_resultContentHandler = newSerializer.asContentHandler(); } catch (IOException ioe) // why? { throw new SAXException(ioe); } if (m_resultContentHandler instanceof DTDHandler) m_resultDTDHandler = (DTDHandler) m_resultContentHandler; if (m_resultContentHandler instanceof LexicalHandler) m_resultLexicalHandler = (LexicalHandler) m_resultContentHandler; m_serializer = newSerializer; } } flushStartDoc(); m_resultContentHandler.startElement(uri, localName, qName, attributes); } /** * Receive notification of the end of an element. * *

By default, do nothing. Application writers may override this * method in a subclass to take specific actions at the end of * each element (such as finalising a tree node or writing * output to a file).

* * @param uri The Namespace URI, or the empty string if the * element has no Namespace URI or if Namespace * processing is not being performed. * @param localName The local name (without prefix), or the * empty string if Namespace processing is not being * performed. * @param qName The qualified name (with prefix), or the * empty string if qualified names are not available. * * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#endElement * * @throws SAXException */ public void endElement(String uri, String localName, String qName) throws SAXException { m_resultContentHandler.endElement(uri, localName, qName); } /** * Receive notification of character data inside an element. * *

By default, do nothing. Application writers may override this * method to take specific actions for each chunk of character data * (such as adding the data to a node or buffer, or printing it to * a file).

* * @param ch The characters. * @param start The start position in the character array. * @param length The number of characters to use from the * character array. * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#characters * * @throws SAXException */ public void characters(char ch[], int start, int length) throws SAXException { flushStartDoc(); m_resultContentHandler.characters(ch, start, length); } /** * Receive notification of ignorable whitespace in element content. * *

By default, do nothing. Application writers may override this * method to take specific actions for each chunk of ignorable * whitespace (such as adding data to a node or buffer, or printing * it to a file).

* * @param ch The whitespace characters. * @param start The start position in the character array. * @param length The number of characters to use from the * character array. * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#ignorableWhitespace * * @throws SAXException */ public void ignorableWhitespace(char ch[], int start, int length) throws SAXException { m_resultContentHandler.ignorableWhitespace(ch, start, length); } /** * Receive notification of a processing instruction. * *

By default, do nothing. Application writers may override this * method in a subclass to take specific actions for each * processing instruction, such as setting status variables or * invoking other methods.

* * @param target The processing instruction target. * @param data The processing instruction data, or null if * none is supplied. * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#processingInstruction * * @throws SAXException */ public void processingInstruction(String target, String data) throws SAXException { flushStartDoc(); m_resultContentHandler.processingInstruction(target, data); } /** * Receive notification of a skipped entity. * *

By default, do nothing. Application writers may override this * method in a subclass to take specific actions for each * processing instruction, such as setting status variables or * invoking other methods.

* * @param name The name of the skipped entity. * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#processingInstruction * * @throws SAXException */ public void skippedEntity(String name) throws SAXException { flushStartDoc(); m_resultContentHandler.skippedEntity(name); } /** * Report the start of DTD declarations, if any. * *

Any declarations are assumed to be in the internal subset * unless otherwise indicated by a {@link #startEntity startEntity} * event.

* *

Note that the start/endDTD events will appear within * the start/endDocument events from ContentHandler and * before the first startElement event.

* * @param name The document type name. * @param publicId The declared public identifier for the * external DTD subset, or null if none was declared. * @param systemId The declared system identifier for the * external DTD subset, or null if none was declared. * @throws SAXException The application may raise an * exception. * @see #endDTD * @see #startEntity */ public void startDTD(String name, String publicId, String systemId) throws SAXException { flushStartDoc(); if (null != m_resultLexicalHandler) m_resultLexicalHandler.startDTD(name, publicId, systemId); } /** * Report the end of DTD declarations. * * @throws SAXException The application may raise an exception. * @see #startDTD */ public void endDTD() throws SAXException { if (null != m_resultLexicalHandler) m_resultLexicalHandler.endDTD(); } /** * Report the beginning of an entity in content. * *

NOTE: entity references in attribute * values -- and the start and end of the document entity -- * are never reported.

* *

The start and end of the external DTD subset are reported * using the pseudo-name "[dtd]". All other events must be * properly nested within start/end entity events.

* *

Note that skipped entities will be reported through the * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity} * event, which is part of the ContentHandler interface.

* * @param name The name of the entity. If it is a parameter * entity, the name will begin with '%'. * @throws SAXException The application may raise an exception. * @see #endEntity * @see org.xml.sax.ext.DeclHandler#internalEntityDecl * @see org.xml.sax.ext.DeclHandler#externalEntityDecl */ public void startEntity(String name) throws SAXException { if (null != m_resultLexicalHandler) m_resultLexicalHandler.startEntity(name); } /** * Report the end of an entity. * * @param name The name of the entity that is ending. * @throws SAXException The application may raise an exception. * @see #startEntity */ public void endEntity(String name) throws SAXException { if (null != m_resultLexicalHandler) m_resultLexicalHandler.endEntity(name); } /** * Report the start of a CDATA section. * *

The contents of the CDATA section will be reported through * the regular {@link org.xml.sax.ContentHandler#characters * characters} event.

* * @throws SAXException The application may raise an exception. * @see #endCDATA */ public void startCDATA() throws SAXException { if (null != m_resultLexicalHandler) m_resultLexicalHandler.startCDATA(); } /** * Report the end of a CDATA section. * * @throws SAXException The application may raise an exception. * @see #startCDATA */ public void endCDATA() throws SAXException { if (null != m_resultLexicalHandler) m_resultLexicalHandler.endCDATA(); } /** * Report an XML comment anywhere in the document. * *

This callback will be used for comments inside or outside the * document element, including comments in the external DTD * subset (if read).

* * @param ch An array holding the characters in the comment. * @param start The starting position in the array. * @param length The number of characters to use from the array. * @throws SAXException The application may raise an exception. */ public void comment(char ch[], int start, int length) throws SAXException { flushStartDoc(); if (null != m_resultLexicalHandler) m_resultLexicalHandler.comment(ch, start, length); } // Implement DeclHandler /** * Report an element type declaration. * *

The content model will consist of the string "EMPTY", the * string "ANY", or a parenthesised group, optionally followed * by an occurrence indicator. The model will be normalized so * that all whitespace is removed,and will include the enclosing * parentheses.

* * @param name The element type name. * @param model The content model as a normalized string. * @exception SAXException The application may raise an exception. */ public void elementDecl (String name, String model) throws SAXException { if (null != m_resultDeclHandler) m_resultDeclHandler.elementDecl(name, model); } /** * Report an attribute type declaration. * *

Only the effective (first) declaration for an attribute will * be reported. The type will be one of the strings "CDATA", * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", * "ENTITIES", or "NOTATION", or a parenthesized token group with * the separator "|" and all whitespace removed.

* * @param eName The name of the associated element. * @param aName The name of the attribute. * @param type A string representing the attribute type. * @param valueDefault A string representing the attribute default * ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if * none of these applies. * @param value A string representing the attribute's default value, * or null if there is none. * @exception SAXException The application may raise an exception. */ public void attributeDecl (String eName, String aName, String type, String valueDefault, String value) throws SAXException { if (null != m_resultDeclHandler) m_resultDeclHandler.attributeDecl(eName, aName, type, valueDefault, value); } /** * Report an internal entity declaration. * *

Only the effective (first) declaration for each entity * will be reported.

* * @param name The name of the entity. If it is a parameter * entity, the name will begin with '%'. * @param value The replacement text of the entity. * @exception SAXException The application may raise an exception. * @see #externalEntityDecl * @see org.xml.sax.DTDHandler#unparsedEntityDecl */ public void internalEntityDecl (String name, String value) throws SAXException { if (null != m_resultDeclHandler) m_resultDeclHandler.internalEntityDecl(name, value); } /** * Report a parsed external entity declaration. * *

Only the effective (first) declaration for each entity * will be reported.

* * @param name The name of the entity. If it is a parameter * entity, the name will begin with '%'. * @param publicId The declared public identifier of the entity, or * null if none was declared. * @param systemId The declared system identifier of the entity. * @exception SAXException The application may raise an exception. * @see #internalEntityDecl * @see org.xml.sax.DTDHandler#unparsedEntityDecl */ public void externalEntityDecl (String name, String publicId, String systemId) throws SAXException { if (null != m_resultDeclHandler) m_resultDeclHandler.externalEntityDecl(name, publicId, systemId); } /** * This is null unless we own the stream. */ private java.io.FileOutputStream m_outputStream = null; /** The content handler where result events will be sent. */ private ContentHandler m_resultContentHandler; /** The lexical handler where result events will be sent. */ private LexicalHandler m_resultLexicalHandler; /** The DTD handler where result events will be sent. */ private DTDHandler m_resultDTDHandler; /** The Decl handler where result events will be sent. */ private DeclHandler m_resultDeclHandler; /** The Serializer, which may or may not be null. */ private Serializer m_serializer; /** The Result object. */ private Result m_result; /** * The system ID, which is unused, but must be returned to fullfill the * TransformerHandler interface. */ private String m_systemID; /** * The parameters, which is unused, but must be returned to fullfill the * Transformer interface. */ private Hashtable m_params; /** The error listener for TrAX errors and warnings. */ private ErrorListener m_errorListener = new org.apache.xml.utils.DefaultErrorHandler(false); /** * The URIResolver, which is unused, but must be returned to fullfill the * TransformerHandler interface. */ URIResolver m_URIResolver; /** The output properties. */ private OutputProperties m_outputFormat; /** Flag to set if we've found the first element, so we can tell if we have * to check to see if we should create an HTML serializer. */ boolean m_foundFirstElement; /** * State of the secure processing feature. */ private boolean m_isSecureProcessing = false; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy