001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: StringValueHandler.java 468652 2006-10-28 07:05:17Z minchau $
020     */
021    
022    package org.apache.xalan.xsltc.runtime;
023    
024    import org.xml.sax.SAXException;
025    
026    import org.apache.xml.serializer.EmptySerializer;
027    
028    /**
029     * @author Jacek Ambroziak
030     * @author Santiago Pericas-Geertsen
031     * @author Morten Jorgensen
032     */
033    public final class StringValueHandler extends EmptySerializer {
034    
035        private StringBuffer _buffer = new StringBuffer();
036        private String _str = null;
037        private static final String EMPTY_STR = "";
038        private boolean m_escaping = false;
039        private int _nestedLevel = 0;
040            
041        public void characters(char[] ch, int off, int len) 
042            throws SAXException 
043        {
044            if (_nestedLevel > 0)
045                return;
046            
047            if (_str != null) {
048                _buffer.append(_str);
049                _str = null;
050            }
051            _buffer.append(ch, off, len);
052        }
053    
054        public String getValue() {
055            if (_buffer.length() != 0) {
056                String result = _buffer.toString();
057                _buffer.setLength(0);
058                return result;
059            }
060            else {
061                String result = _str;
062                _str = null;
063                return (result != null) ? result : EMPTY_STR;
064            }
065        }
066    
067        public void characters(String characters) throws SAXException {
068            if (_nestedLevel > 0)
069                return;
070    
071            if (_str == null && _buffer.length() == 0) {
072                _str = characters;
073            }
074            else {
075                if (_str != null) {
076                    _buffer.append(_str);
077                    _str = null;
078                }
079                
080                _buffer.append(characters);
081            }
082        }
083        
084        public void startElement(String qname) throws SAXException {
085            _nestedLevel++;
086        }
087    
088        public void endElement(String qname) throws SAXException {
089            _nestedLevel--;
090        }
091    
092        // Override the setEscaping method just to indicate that this class is
093        // aware that that method might be called.
094        public boolean setEscaping(boolean bool) {
095            boolean oldEscaping = m_escaping;
096            m_escaping = bool;
097    
098            return bool;
099        }
100    
101        /**
102         * The value of a PI must not contain the substring "?>". Should
103         * that substring be present, replace it by "? >". 
104         */
105        public String getValueOfPI() {
106            final String value = getValue();
107    
108            if (value.indexOf("?>") > 0) {
109                final int n = value.length(); 
110                final StringBuffer valueOfPI = new StringBuffer();
111    
112                for (int i = 0; i < n;) {
113                    final char ch = value.charAt(i++);
114                    if (ch == '?' && value.charAt(i) == '>') {
115                        valueOfPI.append("? >"); i++;
116                    }
117                    else {
118                        valueOfPI.append(ch);
119                    }
120                } 
121                return valueOfPI.toString();
122            }
123            return value;
124        }
125    }