Home | History | Annotate | Download | only in processor
      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