resulttreehandler.java
来自「java jdk 1.4的源码」· Java 代码 · 共 1,929 行 · 第 1/4 页
JAVA
1,929 行
/* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xalan" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, Lotus * Development Corporation., http://www.lotus.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */package org.apache.xalan.transformer;import java.util.Enumeration;import org.apache.xalan.processor.StylesheetHandler;import org.apache.xalan.res.XSLTErrorResources;import org.apache.xalan.templates.Stylesheet;import org.apache.xalan.templates.StylesheetRoot;import org.apache.xalan.templates.ElemTemplate;import org.apache.xalan.templates.ElemTemplateElement;import org.apache.xalan.trace.TraceManager;import org.apache.xalan.trace.GenerateEvent;import org.apache.xml.utils.MutableAttrListImpl;import org.apache.xml.utils.QName;import org.apache.xml.utils.TreeWalker;import org.apache.xml.utils.ObjectPool;import org.apache.xml.utils.XMLCharacterRecognizer;import org.apache.xpath.objects.XObject;import org.apache.xpath.XPathContext;import org.apache.xml.dtm.DTM;import org.apache.xml.dtm.DTMIterator;import org.apache.xml.dtm.DTMFilter;import org.xml.sax.Attributes;import org.xml.sax.ContentHandler;import org.xml.sax.ext.LexicalHandler;import org.xml.sax.SAXParseException;import org.xml.sax.SAXException;import org.xml.sax.ErrorHandler;import org.xml.sax.helpers.NamespaceSupport;import org.apache.xml.utils.NamespaceSupport2;import org.xml.sax.Locator;import javax.xml.transform.TransformerException;import javax.xml.transform.ErrorListener;import javax.xml.transform.Transformer;/** * This class is a layer between the direct calls to the result * tree content handler, and the transformer. For one thing, * we have to delay the call to * getContentHandler().startElement(name, atts) because of the * xsl:attribute and xsl:copy calls. In other words, * the attributes have to be fully collected before you * can call startElement. */public class ResultTreeHandler extends QueuedEvents implements ContentHandler, LexicalHandler, TransformState, org.apache.xml.dtm.ref.dom2dtm.DOM2DTM.CharacterNodeHandler, ErrorHandler{ /** Indicate whether running in Debug mode */ private static final boolean DEBUG = false; /** * Null constructor for object pooling. */ public ResultTreeHandler(){} /** * Create a new result tree handler. The real content * handler will be the ContentHandler passed as an argument. * * @param transformer non-null transformer instance * @param realHandler Content Handler instance */ public ResultTreeHandler(TransformerImpl transformer, ContentHandler realHandler) { init(transformer, realHandler); } /** * Initializer method. * * @param transformer non-null transformer instance * @param realHandler Content Handler instance */ public void init(TransformerImpl transformer, ContentHandler realHandler) { m_transformer = transformer; // m_startDoc.setTransformer(m_transformer); TraceManager tracer = transformer.getTraceManager(); if ((null != tracer) && tracer.hasTraceListeners()) m_tracer = tracer; else m_tracer = null; // m_startDoc.setTraceManager(m_tracer); m_contentHandler = realHandler; // m_startDoc.setContentHandler(m_contentHandler); if (m_contentHandler instanceof LexicalHandler) m_lexicalHandler = (LexicalHandler) m_contentHandler; else m_lexicalHandler = null; m_isTransformClient = (m_contentHandler instanceof TransformerClient); m_cloner = new ClonerToResultTree(transformer, this); // The stylesheet is set at a rather late stage, so I do // this here, though it would probably be better done elsewhere. if (null != m_transformer) m_stylesheetRoot = m_transformer.getStylesheet(); pushDocumentEvent(); // not pending yet. } /** * Bottleneck the startDocument event. * * @throws org.xml.sax.SAXException */ public void startDocument() throws org.xml.sax.SAXException{} /** * Bottleneck the endDocument event. This may be called * more than once in order to make sure the pending start * document is called. * * @throws org.xml.sax.SAXException */ public void endDocument() throws org.xml.sax.SAXException { flushPending(true); if (!m_docEnded) { m_contentHandler.endDocument(); if (null != m_tracer) { GenerateEvent ge = new GenerateEvent(m_transformer, GenerateEvent.EVENTTYPE_ENDDOCUMENT, null); m_tracer.fireGenerateEvent(ge); } m_docEnded = true; m_docPending = false; } } /** * Bottleneck the startElement event. This is used to "pend" an * element, so that attributes can still be added to it before * the real "startElement" is called on the result tree listener. * * @param ns Namespace URI of element * @param localName Local part of qname of element * @param name Name of element * @param atts List of attributes for the element * * @throws org.xml.sax.SAXException */ public void startElement( String ns, String localName, String name, Attributes atts) throws org.xml.sax.SAXException { if (DEBUG) { if (m_elemIsPending) System.out.println("(ResultTreeHandler#startElement - pended: " + m_url + "#" + m_localName); System.out.println("ResultTreeHandler#startElement: " + ns + "#" + localName); // if(null == ns) // { // (new RuntimeException(localName+" has a null namespace!")).printStackTrace(); // } } if(m_docPending) checkForSerializerSwitch(ns, localName); flushPending(true); if (!m_nsContextPushed) { if (DEBUG) System.out.println( "ResultTreeHandler#startElement - push(startElement)"); m_nsSupport.pushContext(); m_nsContextPushed = true; } if (ns != null) ensurePrefixIsDeclared(ns, name); m_name = name; m_url = ns; m_localName = localName; if (null != atts) m_attributes.addAttributes(atts); m_elemIsPending = true; m_elemIsEnded = false; if(m_isTransformClient && (null != m_transformer)) { m_snapshot.m_currentElement = m_transformer.getCurrentElement(); m_snapshot.m_currentTemplate = m_transformer.getCurrentTemplate(); m_snapshot.m_matchedTemplate = m_transformer.getMatchedTemplate(); int currentNodeHandle = m_transformer.getCurrentNode(); DTM dtm = m_transformer.getXPathContext().getDTM(currentNodeHandle); m_snapshot.m_currentNode = dtm.getNode(currentNodeHandle); m_snapshot.m_matchedNode = m_transformer.getMatchedNode(); m_snapshot.m_contextNodeList = m_transformer.getContextNodeList(); // TODO: Need to clone } // initQSE(m_startElement); m_eventCount++; } /** * Bottleneck the endElement event. * * @param ns Namespace URI of element * @param localName Local part of qname of element * @param name Name of element * * @throws org.xml.sax.SAXException */ public void endElement(String ns, String localName, String name) throws org.xml.sax.SAXException { if (DEBUG) { if (m_elemIsPending) System.out.println("(ResultTreeHandler#endElement - pended: " + m_url + "#" + m_localName); System.out.println("ResultTreeHandler#endElement: " + ns + "#" + localName); } flushPending(true); m_contentHandler.endElement(ns, localName, name); if (null != m_tracer) { GenerateEvent ge = new GenerateEvent(m_transformer, GenerateEvent.EVENTTYPE_ENDELEMENT, name, (Attributes)null); m_tracer.fireGenerateEvent(ge); } sendEndPrefixMappings(); popEvent(); if (DEBUG) System.out.println("ResultTreeHandler#startElement pop: " + localName); m_nsSupport.popContext(); } /** Indicate whether a namespace context was pushed */ boolean m_nsContextPushed = false; /** * Begin the scope of a prefix-URI Namespace mapping. * * <p>The information from this event is not necessary for * normal Namespace processing: the SAX XML reader will * automatically replace prefixes for element and attribute * names when the http://xml.org/sax/features/namespaces * feature is true (the default).</p> * * <p>There are cases, however, when applications need to * use prefixes in character data or in attribute values, * where they cannot safely be expanded automatically; the * start/endPrefixMapping event supplies the information * to the application to expand prefixes in those contexts * itself, if necessary.</p> * * <p>Note that start/endPrefixMapping events are not * guaranteed to be properly nested relative to each-other: * all startPrefixMapping events will occur before the * corresponding startElement event, and all endPrefixMapping * events will occur after the corresponding endElement event, * but their order is not guaranteed.</p> * * @param prefix The Namespace prefix being declared. * @param uri The Namespace URI the prefix is mapped to. * @throws org.xml.sax.SAXException The client may throw * an exception during processing. * @see #endPrefixMapping * @see #startElement */ public void startPrefixMapping(String prefix, String uri) throws org.xml.sax.SAXException { startPrefixMapping(prefix, uri, true); } /** * Begin the scope of a prefix-URI Namespace mapping. * * * @param prefix The Namespace prefix being declared. * @param uri The Namespace URI the prefix is mapped to. * @param shouldFlush Indicate whether pending events needs * to be flushed first * * @throws org.xml.sax.SAXException The client may throw * an exception during processing. */ public void startPrefixMapping( String prefix, String uri, boolean shouldFlush) throws org.xml.sax.SAXException { if (shouldFlush) flushPending(false); if (!m_nsContextPushed) { if (DEBUG) System.out.println( "ResultTreeHandler#startPrefixMapping push(startPrefixMapping: " + prefix + ")"); m_nsSupport.pushContext(); m_nsContextPushed = true; } if (null == prefix) prefix = ""; // bit-o-hack, that that's OK String existingURI = m_nsSupport.getURI(prefix); if (null == existingURI) existingURI = ""; if (null == uri) uri = ""; if (!existingURI.equals(uri)) { if (DEBUG) { System.out.println("ResultTreeHandler#startPrefixMapping Prefix: " + prefix); System.out.println("ResultTreeHandler#startPrefixMapping uri: " + uri); } m_nsSupport.declarePrefix(prefix, uri); } } /** * End the scope of a prefix-URI mapping. * * <p>See startPrefixMapping for details. This event will * always occur after the corresponding endElement event, * but the order of endPrefixMapping events is not otherwise * guaranteed.</p> * * @param prefix The prefix that was being mapping. * @throws org.xml.sax.SAXException The client may throw * an exception during processing. * @see #startPrefixMapping * @see #endElement */ public void endPrefixMapping(String prefix) throws org.xml.sax.SAXException{} /** * Bottleneck the characters event. * * @param ch Array of characters to process * @param start start of characters in the array * @param length Number of characters in the array * * @throws org.xml.sax.SAXException */ public void characters(char ch[], int start, int length) throws org.xml.sax.SAXException { // It would be nice to suppress all whitespace before the // first element, but this is going to cause potential problems with // text serialization and with text entities (right term?). // So this really needs to be done at the serializer level. /*if (m_startDoc.isPending && XMLCharacterRecognizer.isWhiteSpace(ch, start, length)) return;*/ if (DEBUG) { System.out.print("ResultTreeHandler#characters: "); int n = start + length; for (int i = start; i < n; i++) { if (Character.isWhitespace(ch[i])) System.out.print("\\" + ((int) ch[i])); else System.out.print(ch[i]); } System.out.println(""); } flushPending(true); m_contentHandler.characters(ch, start, length); if (null != m_tracer)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?