1/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5/*
6 * Licensed to the Apache Software Foundation (ASF) under one or more
7 * contributor license agreements.  See the NOTICE file distributed with
8 * this work for additional information regarding copyright ownership.
9 * The ASF licenses this file to You under the Apache License, Version 2.0
10 * (the "License"); you may not use this file except in compliance with
11 * the License.  You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22package com.sun.org.apache.xalan.internal.xsltc.runtime;
23
24import org.xml.sax.SAXException;
25
26import com.sun.org.apache.xml.internal.serializer.EmptySerializer;
27
28/**
29 * @author Jacek Ambroziak
30 * @author Santiago Pericas-Geertsen
31 * @author Morten Jorgensen
32 */
33public final class StringValueHandler extends EmptySerializer {
34
35    private StringBuilder _buffer = new StringBuilder();
36    private String _str = null;
37    private static final String EMPTY_STR = "";
38    private boolean m_escaping = false;
39    private int _nestedLevel = 0;
40
41    public void characters(char[] ch, int off, int len)
42        throws SAXException
43    {
44        if (_nestedLevel > 0)
45            return;
46
47        if (_str != null) {
48            _buffer.append(_str);
49            _str = null;
50        }
51        _buffer.append(ch, off, len);
52    }
53
54    public String getValue() {
55        if (_buffer.length() != 0) {
56            String result = _buffer.toString();
57            _buffer.setLength(0);
58            return result;
59        }
60        else {
61            String result = _str;
62            _str = null;
63            return (result != null) ? result : EMPTY_STR;
64        }
65    }
66
67    public void characters(String characters) throws SAXException {
68        if (_nestedLevel > 0)
69            return;
70
71        if (_str == null && _buffer.length() == 0) {
72            _str = characters;
73        }
74        else {
75            if (_str != null) {
76                _buffer.append(_str);
77                _str = null;
78            }
79
80            _buffer.append(characters);
81        }
82    }
83
84    public void startElement(String qname) throws SAXException {
85        _nestedLevel++;
86    }
87
88    public void endElement(String qname) throws SAXException {
89        _nestedLevel--;
90    }
91
92    // Override the setEscaping method just to indicate that this class is
93    // aware that that method might be called.
94    public boolean setEscaping(boolean bool) {
95        boolean oldEscaping = m_escaping;
96        m_escaping = bool;
97
98        return bool;
99    }
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 StringBuilder valueOfPI = new StringBuilder();
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}
126