1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 /* 19 * $Id: ProcessorCharacters.java 468640 2006-10-28 06:53:53Z minchau $ 20 */ 21 package org.apache.xalan.processor; 22 23 import javax.xml.transform.TransformerException; 24 25 import org.apache.xalan.templates.ElemTemplateElement; 26 import org.apache.xalan.templates.ElemText; 27 import org.apache.xalan.templates.ElemTextLiteral; 28 import org.apache.xml.utils.XMLCharacterRecognizer; 29 30 import org.w3c.dom.Node; 31 32 /** 33 * This class processes character events for a XSLT template element. 34 * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a> 35 * @see <a href="http://www.w3.org/TR/xslt#section-Creating-the-Result-Tree">section-Creating-the-Result-Tree in XSLT Specification</a> 36 */ 37 public class ProcessorCharacters extends XSLTElementProcessor 38 { 39 static final long serialVersionUID = 8632900007814162650L; 40 41 /** 42 * Receive notification of the start of the non-text event. This 43 * is sent to the current processor when any non-text event occurs. 44 * 45 * @param handler non-null reference to current StylesheetHandler that is constructing the Templates. 46 */ 47 public void startNonText(StylesheetHandler handler) throws org.xml.sax.SAXException 48 { 49 if (this == handler.getCurrentProcessor()) 50 { 51 handler.popProcessor(); 52 } 53 54 int nChars = m_accumulator.length(); 55 56 if ((nChars > 0) 57 && ((null != m_xslTextElement) 58 ||!XMLCharacterRecognizer.isWhiteSpace(m_accumulator)) 59 || handler.isSpacePreserve()) 60 { 61 ElemTextLiteral elem = new ElemTextLiteral(); 62 63 elem.setDOMBackPointer(m_firstBackPointer); 64 elem.setLocaterInfo(handler.getLocator()); 65 try 66 { 67 elem.setPrefixes(handler.getNamespaceSupport()); 68 } 69 catch(TransformerException te) 70 { 71 throw new org.xml.sax.SAXException(te); 72 } 73 74 boolean doe = (null != m_xslTextElement) 75 ? m_xslTextElement.getDisableOutputEscaping() : false; 76 77 elem.setDisableOutputEscaping(doe); 78 elem.setPreserveSpace(true); 79 80 char[] chars = new char[nChars]; 81 82 m_accumulator.getChars(0, nChars, chars, 0); 83 elem.setChars(chars); 84 85 ElemTemplateElement parent = handler.getElemTemplateElement(); 86 87 parent.appendChild(elem); 88 } 89 90 m_accumulator.setLength(0); 91 m_firstBackPointer = null; 92 } 93 94 protected Node m_firstBackPointer = null; 95 96 /** 97 * Receive notification of character data inside an element. 98 * 99 * 100 * @param handler non-null reference to current StylesheetHandler that is constructing the Templates. 101 * @param ch The characters. 102 * @param start The start position in the character array. 103 * @param length The number of characters to use from the 104 * character array. 105 * @throws org.xml.sax.SAXException Any SAX exception, possibly 106 * wrapping another exception. 107 * @see org.xml.sax.ContentHandler#characters 108 */ 109 public void characters( 110 StylesheetHandler handler, char ch[], int start, int length) 111 throws org.xml.sax.SAXException 112 { 113 114 m_accumulator.append(ch, start, length); 115 116 if(null == m_firstBackPointer) 117 m_firstBackPointer = handler.getOriginatingNode(); 118 119 // Catch all events until a non-character event. 120 if (this != handler.getCurrentProcessor()) 121 handler.pushProcessor(this); 122 } 123 124 /** 125 * Receive notification of the end of an element. 126 * 127 * @param handler The calling StylesheetHandler/TemplatesBuilder. 128 * @param uri The Namespace URI, or the empty string if the 129 * element has no Namespace URI or if Namespace 130 * processing is not being performed. 131 * @param localName The local name (without prefix), or the 132 * empty string if Namespace processing is not being 133 * performed. 134 * @param rawName The raw XML 1.0 name (with prefix), or the 135 * empty string if raw names are not available. 136 * @see org.apache.xalan.processor.StylesheetHandler#startElement 137 * @see org.apache.xalan.processor.StylesheetHandler#endElement 138 * @see org.xml.sax.ContentHandler#startElement 139 * @see org.xml.sax.ContentHandler#endElement 140 * @see org.xml.sax.Attributes 141 */ 142 public void endElement( 143 StylesheetHandler handler, String uri, String localName, String rawName) 144 throws org.xml.sax.SAXException 145 { 146 147 // Since this has been installed as the current processor, we 148 // may get and end element event, in which case, we pop and clear 149 // and then call the real element processor. 150 startNonText(handler); 151 handler.getCurrentProcessor().endElement(handler, uri, localName, 152 rawName); 153 handler.popProcessor(); 154 } 155 156 /** 157 * Accumulate characters, until a non-whitespace event has 158 * occured. 159 */ 160 private StringBuffer m_accumulator = new StringBuffer(); 161 162 /** 163 * The xsl:text processor will call this to set a 164 * preserve space state. 165 */ 166 private ElemText m_xslTextElement; 167 168 /** 169 * Set the current setXslTextElement. The xsl:text 170 * processor will call this to set a preserve space state. 171 * 172 * @param xslTextElement The current xslTextElement that 173 * is preserving state, or null. 174 */ 175 void setXslTextElement(ElemText xslTextElement) 176 { 177 m_xslTextElement = xslTextElement; 178 } 179 } 180