/* * reserved comment block * DO NOT REMOVE OR ALTER! */ /* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed 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: ToSAXHandler.java,v 1.2.4.1 2005/09/22 11:03:15 pvedula Exp $ */ package com.sun.org.apache.xml.internal.serializer; import java.util.Vector; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.ext.LexicalHandler; /** * This class is used to provide a base behavior to be inherited * by other To...SAXHandler serializers. * * This class is not a public API. * * @xsl.usage internal */ public abstract class ToSAXHandler extends SerializerBase { public ToSAXHandler() { } public ToSAXHandler( ContentHandler hdlr, LexicalHandler lex, String encoding) { setContentHandler(hdlr); setLexHandler(lex); setEncoding(encoding); } public ToSAXHandler(ContentHandler handler, String encoding) { setContentHandler(handler); setEncoding(encoding); } /** * Underlying SAX handler. Taken from XSLTC */ protected ContentHandler m_saxHandler; /** * Underlying LexicalHandler. Taken from XSLTC */ protected LexicalHandler m_lexHandler; /** * A startPrefixMapping() call on a ToSAXHandler will pass that call * on to the wrapped ContentHandler, but should we also mirror these calls * with matching attributes, if so this field is true. * For example if this field is true then a call such as * startPrefixMapping("prefix1","uri1") will also cause the additional * internally generated attribute xmlns:prefix1="uri1" to be effectively added * to the attributes passed to the wrapped ContentHandler. */ private boolean m_shouldGenerateNSAttribute = true; /** If this is true, then the content handler wrapped by this * serializer implements the TransformState interface which * will give the content handler access to the state of * the transform. */ protected TransformStateSetter m_state = null; /** * Pass callback to the SAX Handler */ protected void startDocumentInternal() throws SAXException { if (m_needToCallStartDocument) { super.startDocumentInternal(); m_saxHandler.startDocument(); m_needToCallStartDocument = false; } } /** * Do nothing. * @see org.xml.sax.ext.LexicalHandler#startDTD(String, String, String) */ public void startDTD(String arg0, String arg1, String arg2) throws SAXException { // do nothing for now } /** * Receive notification of character data. * * @param characters The string of characters to process. * * @throws org.xml.sax.SAXException * * @see ExtendedContentHandler#characters(String) */ public void characters(String characters) throws SAXException { final int len = characters.length(); if (len > m_charsBuff.length) { m_charsBuff = new char[len*2 + 1]; } characters.getChars(0,len, m_charsBuff, 0); characters(m_charsBuff, 0, len); } /** * Receive notification of a comment. * * @see ExtendedLexicalHandler#comment(String) */ public void comment(String comment) throws SAXException { flushPending(); // Ignore if a lexical handler has not been set if (m_lexHandler != null) { final int len = comment.length(); if (len > m_charsBuff.length) { m_charsBuff = new char[len*2 + 1]; } comment.getChars(0,len, m_charsBuff, 0); m_lexHandler.comment(m_charsBuff, 0, len); // time to fire off comment event if (m_tracer != null) super.fireCommentEvent(m_charsBuff, 0, len); } } /** * Do nothing as this is an abstract class. All subclasses will need to * define their behavior if it is different. * @see org.xml.sax.ContentHandler#processingInstruction(String, String) */ public void processingInstruction(String target, String data) throws SAXException { // Redefined in SAXXMLOutput } protected void closeStartTag() throws SAXException { } protected void closeCDATA() throws SAXException { // Redefined in SAXXMLOutput } /** * Receive notification of the beginning of an element, although this is a * SAX method additional namespace or attribute information can occur before * or after this call, that is associated with this element. * * @throws org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @see org.xml.sax.ContentHandler#startElement * @see org.xml.sax.ContentHandler#endElement * @see org.xml.sax.AttributeList * * @throws org.xml.sax.SAXException * * @see org.xml.sax.ContentHandler#startElement(String,String,String,Attributes) */ public void startElement( String arg0, String arg1, String arg2, Attributes arg3) throws SAXException { if (m_state != null) { m_state.resetState(getTransformer()); } // fire off the start element event if (m_tracer != null) super.fireStartElem(arg2); } /** * Sets the LexicalHandler. * @param _lexHandler The LexicalHandler to set */ public void setLexHandler(LexicalHandler _lexHandler) { this.m_lexHandler = _lexHandler; } /** * Sets the SAX ContentHandler. * @param _saxHandler The ContentHandler to set */ public void setContentHandler(ContentHandler _saxHandler) { this.m_saxHandler = _saxHandler; if (m_lexHandler == null && _saxHandler instanceof LexicalHandler) { // we are not overwriting an existing LexicalHandler, and _saxHandler // is also implements LexicalHandler, so lets use it m_lexHandler = (LexicalHandler) _saxHandler; } } /** * Does nothing. The setting of CDATA section elements has an impact on * stream serializers. * @see SerializationHandler#setCdataSectionElements(java.util.Vector) */ public void setCdataSectionElements(Vector URI_and_localNames) { // do nothing } /** Set whether or not namespace declarations (e.g. * xmlns:foo) should appear as attributes of * elements * @param doOutputNSAttr whether or not namespace declarations * should appear as attributes */ public void setShouldOutputNSAttr(boolean doOutputNSAttr) { m_shouldGenerateNSAttribute = doOutputNSAttr; } /** * Returns true if namespace declarations from calls such as * startPrefixMapping("prefix1","uri1") should * also be mirrored with self generated additional attributes of elements * that declare the namespace, for example the attribute xmlns:prefix1="uri1" */ boolean getShouldOutputNSAttr() { return m_shouldGenerateNSAttribute; } /** * This method flushes any pending events, which can be startDocument() * closing the opening tag of an element, or closing an open CDATA section. */ public void flushPending() throws SAXException { if (m_needToCallStartDocument) { startDocumentInternal(); m_needToCallStartDocument = false; } if (m_elemContext.m_startTagOpen) { closeStartTag(); m_elemContext.m_startTagOpen = false; } if (m_cdataTagOpen) { closeCDATA(); m_cdataTagOpen = false; } } /** * Pass in a reference to a TransformState object, which * can be used during SAX ContentHandler events to obtain * information about he state of the transformation. This * method will be called before each startDocument event. * * @param ts A reference to a TransformState object */ public void setTransformState(TransformStateSetter ts) { this.m_state = ts; } /** * Receives notification that an element starts, but attributes are not * fully known yet. * * @param uri the URI of the namespace of the element (optional) * @param localName the element name, but without prefix (optional) * @param qName the element name, with prefix, if any (required) * * @see ExtendedContentHandler#startElement(String, String, String) */ public void startElement(String uri, String localName, String qName) throws SAXException { if (m_state != null) { m_state.resetState(getTransformer()); } // fire off the start element event if (m_tracer != null) super.fireStartElem(qName); } /** * An element starts, but attributes are not fully known yet. * * @param qName the element name, with prefix (if any). * @see ExtendedContentHandler#startElement(String) */ public void startElement(String qName) throws SAXException { if (m_state != null) { m_state.resetState(getTransformer()); } // fire off the start element event if (m_tracer != null) super.fireStartElem(qName); } /** * This method gets the node's value as a String and uses that String as if * it were an input character notification. * @param node the Node to serialize * @throws org.xml.sax.SAXException */ public void characters(org.w3c.dom.Node node) throws org.xml.sax.SAXException { // remember the current node if (m_state != null) { m_state.setCurrentNode(node); } // Get the node's value as a String and use that String as if // it were an input character notification. String data = node.getNodeValue(); if (data != null) { this.characters(data); } } /** * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException) */ public void fatalError(SAXParseException exc) throws SAXException { super.fatalError(exc); m_needToCallStartDocument = false; if (m_saxHandler instanceof ErrorHandler) { ((ErrorHandler)m_saxHandler).fatalError(exc); } } /** * @see org.xml.sax.ErrorHandler#error(SAXParseException) */ public void error(SAXParseException exc) throws SAXException { super.error(exc); if (m_saxHandler instanceof ErrorHandler) ((ErrorHandler)m_saxHandler).error(exc); } /** * @see org.xml.sax.ErrorHandler#warning(SAXParseException) */ public void warning(SAXParseException exc) throws SAXException { super.warning(exc); if (m_saxHandler instanceof ErrorHandler) ((ErrorHandler)m_saxHandler).warning(exc); } /** * Try's to reset the super class and reset this class for * re-use, so that you don't need to create a new serializer * (mostly for performance reasons). * * @return true if the class was successfuly reset. * @see Serializer#reset() */ public boolean reset() { boolean wasReset = false; if (super.reset()) { resetToSAXHandler(); wasReset = true; } return wasReset; } /** * Reset all of the fields owned by ToSAXHandler class * */ private void resetToSAXHandler() { this.m_lexHandler = null; this.m_saxHandler = null; this.m_state = null; this.m_shouldGenerateNSAttribute = false; } /** * Add a unique attribute */ public void addUniqueAttribute(String qName, String value, int flags) throws SAXException { addAttribute(qName, value); } }