19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: ToHTMLStream.java 468654 2006-10-28 07:09:23Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.serializer;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.IOException;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Properties;
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.Result;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.utils.MsgKey;
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.serializer.utils.Utils;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.Attributes;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.SAXException;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This serializer takes a series of SAX or
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * SAX-like events and writes its output
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to the given stream.
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class is not a public API, it is public
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * because it is used from another package.
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage internal
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class ToHTMLStream extends ToStream
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** This flag is set while receiving events from the DTD */
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected boolean m_inDTD = false;
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** True if the current element is a block element.  (seems like
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  this needs to be a stack. -sb). */
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private boolean m_inBlockElem = false;
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Map that tells which XML characters should have special treatment, and it
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  provides character to entity name lookup.
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final CharInfo m_htmlcharInfo =
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//        new CharInfo(CharInfo.HTML_ENTITIES_RESOURCE);
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        CharInfo.getCharInfo(CharInfo.HTML_ENTITIES_RESOURCE, Method.HTML);
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** A digital search trie for fast, case insensitive lookup of ElemDesc objects. */
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static final Trie m_elementFlags = new Trie();
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static {
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        initTagReference(m_elementFlags);
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static void initTagReference(Trie m_elementFlags) {
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // HTML 4.0 loose DTD
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("BASEFONT", new ElemDesc(0 | ElemDesc.EMPTY));
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "FRAME",
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("FRAMESET", new ElemDesc(0 | ElemDesc.BLOCK));
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("NOFRAMES", new ElemDesc(0 | ElemDesc.BLOCK));
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "ISINDEX",
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "APPLET",
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.WHITESPACESENSITIVE));
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("CENTER", new ElemDesc(0 | ElemDesc.BLOCK));
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("DIR", new ElemDesc(0 | ElemDesc.BLOCK));
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("MENU", new ElemDesc(0 | ElemDesc.BLOCK));
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // HTML 4.0 strict DTD
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("TT", new ElemDesc(0 | ElemDesc.FONTSTYLE));
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("I", new ElemDesc(0 | ElemDesc.FONTSTYLE));
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("B", new ElemDesc(0 | ElemDesc.FONTSTYLE));
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("BIG", new ElemDesc(0 | ElemDesc.FONTSTYLE));
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("SMALL", new ElemDesc(0 | ElemDesc.FONTSTYLE));
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("EM", new ElemDesc(0 | ElemDesc.PHRASE));
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("STRONG", new ElemDesc(0 | ElemDesc.PHRASE));
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("DFN", new ElemDesc(0 | ElemDesc.PHRASE));
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("CODE", new ElemDesc(0 | ElemDesc.PHRASE));
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("SAMP", new ElemDesc(0 | ElemDesc.PHRASE));
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("KBD", new ElemDesc(0 | ElemDesc.PHRASE));
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("VAR", new ElemDesc(0 | ElemDesc.PHRASE));
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("CITE", new ElemDesc(0 | ElemDesc.PHRASE));
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("ABBR", new ElemDesc(0 | ElemDesc.PHRASE));
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("ACRONYM", new ElemDesc(0 | ElemDesc.PHRASE));
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "SUP",
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL));
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "SUB",
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL));
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "SPAN",
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL));
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "BDO",
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL));
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "BR",
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.SPECIAL
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.ASPECIAL
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.EMPTY
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK));
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("BODY", new ElemDesc(0 | ElemDesc.BLOCK));
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "ADDRESS",
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET));
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "DIV",
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET));
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("A", new ElemDesc(0 | ElemDesc.SPECIAL));
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "MAP",
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL | ElemDesc.BLOCK));
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "AREA",
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "LINK",
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0 | ElemDesc.HEADMISC | ElemDesc.EMPTY | ElemDesc.BLOCK));
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "IMG",
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.SPECIAL
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.ASPECIAL
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.EMPTY
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.WHITESPACESENSITIVE));
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "OBJECT",
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.SPECIAL
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.ASPECIAL
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.HEADMISC
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.WHITESPACESENSITIVE));
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("PARAM", new ElemDesc(0 | ElemDesc.EMPTY));
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "HR",
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.EMPTY));
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "P",
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET));
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "H1",
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "H2",
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "H3",
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "H4",
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "H5",
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "H6",
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.HEAD | ElemDesc.BLOCK));
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "PRE",
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.PREFORMATTED | ElemDesc.BLOCK));
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "Q",
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.SPECIAL | ElemDesc.ASPECIAL));
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "BLOCKQUOTE",
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET));
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("INS", new ElemDesc(0));
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("DEL", new ElemDesc(0));
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "DL",
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET));
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("DT", new ElemDesc(0 | ElemDesc.BLOCK));
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("DD", new ElemDesc(0 | ElemDesc.BLOCK));
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "OL",
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.LIST | ElemDesc.BLOCK));
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "UL",
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.LIST | ElemDesc.BLOCK));
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("LI", new ElemDesc(0 | ElemDesc.BLOCK));
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("FORM", new ElemDesc(0 | ElemDesc.BLOCK));
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("LABEL", new ElemDesc(0 | ElemDesc.FORMCTRL));
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "INPUT",
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0 | ElemDesc.FORMCTRL | ElemDesc.INLINELABEL | ElemDesc.EMPTY));
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "SELECT",
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.FORMCTRL | ElemDesc.INLINELABEL));
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("OPTGROUP", new ElemDesc(0));
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("OPTION", new ElemDesc(0));
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "TEXTAREA",
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.FORMCTRL | ElemDesc.INLINELABEL));
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "FIELDSET",
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.BLOCKFORM));
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("LEGEND", new ElemDesc(0));
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "BUTTON",
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.FORMCTRL | ElemDesc.INLINELABEL));
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "TABLE",
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET));
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("CAPTION", new ElemDesc(0 | ElemDesc.BLOCK));
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("THEAD", new ElemDesc(0 | ElemDesc.BLOCK));
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("TFOOT", new ElemDesc(0 | ElemDesc.BLOCK));
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("TBODY", new ElemDesc(0 | ElemDesc.BLOCK));
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("COLGROUP", new ElemDesc(0 | ElemDesc.BLOCK));
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "COL",
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("TR", new ElemDesc(0 | ElemDesc.BLOCK));
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("TH", new ElemDesc(0));
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("TD", new ElemDesc(0));
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "HEAD",
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.HEADELEM));
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("TITLE", new ElemDesc(0 | ElemDesc.BLOCK));
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "BASE",
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(0 | ElemDesc.EMPTY | ElemDesc.BLOCK));
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "META",
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0 | ElemDesc.HEADMISC | ElemDesc.EMPTY | ElemDesc.BLOCK));
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "STYLE",
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0 | ElemDesc.HEADMISC | ElemDesc.RAW | ElemDesc.BLOCK));
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "SCRIPT",
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.SPECIAL
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.ASPECIAL
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.HEADMISC
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.RAW));
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "NOSCRIPT",
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET));
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("HTML", new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.HTMLELEM));
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // From "John Ky" <hand@syd.speednet.com.au
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Transitional Document Type Definition ()
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/sgml/loosedtd.html#basefont
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("FONT", new ElemDesc(0 | ElemDesc.FONTSTYLE));
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/present/graphics.html#edef-STRIKE
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("S", new ElemDesc(0 | ElemDesc.FONTSTYLE));
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("STRIKE", new ElemDesc(0 | ElemDesc.FONTSTYLE));
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/present/graphics.html#edef-U
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("U", new ElemDesc(0 | ElemDesc.FONTSTYLE));
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // From "John Ky" <hand@syd.speednet.com.au
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put("NOBR", new ElemDesc(0 | ElemDesc.FONTSTYLE));
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // HTML 4.0, section 16.5
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "IFRAME",
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET));
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Netscape 4 extension
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "LAYER",
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET));
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Netscape 4 extension
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_elementFlags.put(
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "ILAYER",
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            new ElemDesc(
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                0
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCK
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORM
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | ElemDesc.BLOCKFORMFIELDSET));
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // NOW FOR ATTRIBUTE INFORMATION . . .
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ElemDesc elemDesc;
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("a");
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("NAME", ElemDesc.ATTRURL);
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("area");
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("NOHREF", ElemDesc.ATTREMPTY);
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("base");
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("button");
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("blockquote");
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("CITE", ElemDesc.ATTRURL);
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("del");
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("CITE", ElemDesc.ATTRURL);
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("dir");
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("div");
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("SRC", ElemDesc.ATTRURL); // Netscape 4 extension
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("NOWRAP", ElemDesc.ATTREMPTY); // Internet-Explorer extension
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("dl");
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("form");
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("ACTION", ElemDesc.ATTRURL);
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Attribution to: "Voytenko, Dimitry" <DVoytenko@SECTORBASE.COM>
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("frame");
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("LONGDESC", ElemDesc.ATTRURL);
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("NORESIZE",ElemDesc.ATTREMPTY);
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("head");
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("PROFILE", ElemDesc.ATTRURL);
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("hr");
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("NOSHADE", ElemDesc.ATTREMPTY);
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // HTML 4.0, section 16.5
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("iframe");
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("LONGDESC", ElemDesc.ATTRURL);
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Netscape 4 extension
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("ilayer");
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("img");
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("LONGDESC", ElemDesc.ATTRURL);
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("USEMAP", ElemDesc.ATTRURL);
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("ISMAP", ElemDesc.ATTREMPTY);
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("input");
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("USEMAP", ElemDesc.ATTRURL);
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("CHECKED", ElemDesc.ATTREMPTY);
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("ISMAP", ElemDesc.ATTREMPTY);
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("READONLY", ElemDesc.ATTREMPTY);
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("ins");
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("CITE", ElemDesc.ATTRURL);
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Netscape 4 extension
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("layer");
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("link");
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("menu");
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("object");
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("CLASSID", ElemDesc.ATTRURL);
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("CODEBASE", ElemDesc.ATTRURL);
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("DATA", ElemDesc.ATTRURL);
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("ARCHIVE", ElemDesc.ATTRURL);
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("USEMAP", ElemDesc.ATTRURL);
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("DECLARE", ElemDesc.ATTREMPTY);
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("ol");
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("optgroup");
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("option");
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("SELECTED", ElemDesc.ATTREMPTY);
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("q");
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("CITE", ElemDesc.ATTRURL);
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("script");
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("FOR", ElemDesc.ATTRURL);
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("DEFER", ElemDesc.ATTREMPTY);
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("select");
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("MULTIPLE", ElemDesc.ATTREMPTY);
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("table");
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("NOWRAP", ElemDesc.ATTREMPTY); // Internet-Explorer extension
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("td");
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("NOWRAP", ElemDesc.ATTREMPTY);
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("textarea");
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("DISABLED", ElemDesc.ATTREMPTY);
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("READONLY", ElemDesc.ATTREMPTY);
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("th");
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("NOWRAP", ElemDesc.ATTREMPTY);
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // The nowrap attribute of a tr element is both
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // a Netscape and Internet-Explorer extension
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("tr");
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("NOWRAP", ElemDesc.ATTREMPTY);
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ----------------------------------------------
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc = (ElemDesc) m_elementFlags.get("ul");
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Dummy element for elements not found.
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static private final ElemDesc m_dummy = new ElemDesc(0 | ElemDesc.BLOCK);
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** True if URLs should be specially escaped with the %xx form. */
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private boolean m_specialEscapeURLs = true;
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** True if the META tag should be omitted. */
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private boolean m_omitMetaTag = false;
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tells if the formatter should use special URL escaping.
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param bool True if URLs should be specially escaped with the %xx form.
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void setSpecialEscapeURLs(boolean bool)
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_specialEscapeURLs = bool;
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tells if the formatter should omit the META tag.
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param bool True if the META tag should be omitted.
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void setOmitMetaTag(boolean bool)
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_omitMetaTag = bool;
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Specifies an output format for this serializer. It the
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * serializer has already been associated with an output format,
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * it will switch to the new format. This method should not be
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * called while the serializer is in the process of serializing
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * a document.
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method can be called multiple times before starting
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the serialization of a particular result-tree. In principle
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * all serialization parameters can be changed, with the exception
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * of method="html" (it must be method="html" otherwise we
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * shouldn't even have a ToHTMLStream object here!)
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param format The output format or serialzation parameters
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * to use.
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void setOutputFormat(Properties format)
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /*
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * If "format" does not contain the property
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * S_USE_URL_ESCAPING, then don't set this value at all,
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * just leave as-is rather than explicitly setting it.
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String value;
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        value = format.getProperty(OutputPropertiesFactory.S_USE_URL_ESCAPING);
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (value != null) {
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_specialEscapeURLs =
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                OutputPropertyUtils.getBooleanProperty(
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    OutputPropertiesFactory.S_USE_URL_ESCAPING,
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    format);
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /*
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * If "format" does not contain the property
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * S_OMIT_META_TAG, then don't set this value at all,
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * just leave as-is rather than explicitly setting it.
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        value = format.getProperty(OutputPropertiesFactory.S_OMIT_META_TAG);
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (value != null) {
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           m_omitMetaTag =
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                OutputPropertyUtils.getBooleanProperty(
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    OutputPropertiesFactory.S_OMIT_META_TAG,
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    format);
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        super.setOutputFormat(format);
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tells if the formatter should use special URL escaping.
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return True if URLs should be specially escaped with the %xx form.
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final boolean getSpecialEscapeURLs()
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_specialEscapeURLs;
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tells if the formatter should omit the META tag.
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return True if the META tag should be omitted.
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final boolean getOmitMetaTag()
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_omitMetaTag;
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get a description of the given element.
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param name non-null name of element, case insensitive.
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return non-null reference to ElemDesc, which may be m_dummy if no
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *         element description matches the given name.
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public static final ElemDesc getElemDesc(String name)
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /* this method used to return m_dummy  when name was null
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * but now it doesn't check and and requires non-null name.
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Object obj = m_elementFlags.get(name);
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null != obj)
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return (ElemDesc)obj;
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_dummy;
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * A Trie that is just a copy of the "static" one.
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * We need this one to be able to use the faster, but not thread-safe
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * method Trie.get2(name)
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private Trie m_htmlInfo = new Trie(m_elementFlags);
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Calls to this method could be replaced with calls to
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * getElemDesc(name), but this one should be faster.
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private ElemDesc getElemDesc2(String name)
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Object obj = m_htmlInfo.get2(name);
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null != obj)
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return (ElemDesc)obj;
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_dummy;
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Default constructor.
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public ToHTMLStream()
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        super();
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // we are just constructing this thing, no output properties
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // have been used, so we will set the right default for
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // indenting anyways
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_doIndent = true;
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_charInfo = m_htmlcharInfo;
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // initialize namespaces
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_prefixMap = new NamespaceMappings();
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** The name of the current element. */
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//    private String m_currentElementName = null;
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Receive notification of the beginning of a document.
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException Any SAX exception, possibly
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *            wrapping another exception.
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void startDocumentInternal() throws org.xml.sax.SAXException
6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        super.startDocumentInternal();
6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_needToCallStartDocument = false;
6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_needToOutputDocTypeDecl = true;
6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_startNewLine = false;
6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        setOmitXMLDeclaration(true);
6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method should only get called once.
6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * If a DOCTYPE declaration needs to get written out, it will
6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * be written out. If it doesn't need to be written out, then
6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the call to this method has no effect.
6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private void outputDocTypeDecl(String name) throws SAXException {
7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (true == m_needToOutputDocTypeDecl)
7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String doctypeSystem = getDoctypeSystem();
7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String doctypePublic = getDoctypePublic();
7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((null != doctypeSystem) || (null != doctypePublic))
7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                final java.io.Writer writer = m_writer;
7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                try
7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write("<!DOCTYPE ");
7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(name);
7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (null != doctypePublic)
7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(" PUBLIC \"");
7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(doctypePublic);
7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write('"');
7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (null != doctypeSystem)
7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (null == doctypePublic)
7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(" SYSTEM \"");
7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    else
7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(" \"");
7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(doctypeSystem);
7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write('"');
7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write('>');
7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                outputLineSep();
7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                catch(IOException e)
7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    throw new SAXException(e);
7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_needToOutputDocTypeDecl = false;
7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Receive notification of the end of a document.
7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException Any SAX exception, possibly
7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *            wrapping another exception.
7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final void endDocument() throws org.xml.sax.SAXException
7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        flushPending();
7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_doIndent && !m_isprevtext)
7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            try
7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            outputLineSep();
7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            catch(IOException e)
7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                throw new SAXException(e);
7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        flushWriter();
7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_tracer != null)
7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            super.fireEndDoc();
7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  Receive notification of the beginning of an element.
7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param namespaceURI
7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param localName
7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param name The element type name.
7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param atts The attributes attached to the element, if any.
7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @throws org.xml.sax.SAXException Any SAX exception, possibly
7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *             wrapping another exception.
7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @see #endElement
7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @see org.xml.sax.AttributeList
7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void startElement(
7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String namespaceURI,
7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String localName,
7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String name,
7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Attributes atts)
7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws org.xml.sax.SAXException
7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ElemContext elemContext = m_elemContext;
7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // clean up any pending things first
7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (elemContext.m_startTagOpen)
7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            closeStartTag();
8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            elemContext.m_startTagOpen = false;
8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (m_cdataTagOpen)
8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            closeCDATA();
8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_cdataTagOpen = false;
8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (m_needToCallStartDocument)
8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            startDocumentInternal();
8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_needToCallStartDocument = false;
8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_needToOutputDocTypeDecl) {
8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String n = name;
8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (n == null || n.length() == 0) {
8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // If the lexical QName is not given
8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // use the localName in the DOCTYPE
8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                n = localName;
8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            outputDocTypeDecl(n);
8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // if this element has a namespace then treat it like XML
8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null != namespaceURI && namespaceURI.length() > 0)
8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            super.startElement(namespaceURI, localName, name, atts);
8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return;
8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        try
8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // getElemDesc2(name) is faster than getElemDesc(name)
8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            ElemDesc elemDesc = getElemDesc2(name);
8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int elemFlags = elemDesc.getFlags();
8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // deal with indentation issues first
8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_doIndent)
8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                boolean isBlockElement = (elemFlags & ElemDesc.BLOCK) != 0;
8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (m_ispreserve)
8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_ispreserve = false;
8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else if (
8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    (null != elemContext.m_elementName)
8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    && (!m_inBlockElem
8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        || isBlockElement) /* && !isWhiteSpaceSensitive */
8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    )
8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_startNewLine = true;
8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    indent();
8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_inBlockElem = !isBlockElement;
8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // save any attributes for later processing
8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (atts != null)
8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                addAttributes(atts);
8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_isprevtext = false;
8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final java.io.Writer writer = m_writer;
8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write('<');
8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write(name);
8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_tracer != null)
8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                firePseudoAttributes();
8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((elemFlags & ElemDesc.EMPTY) != 0)
8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // an optimization for elements which are expected
8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // to be empty.
8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_elemContext = elemContext.push();
8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                /* XSLTC sometimes calls namespaceAfterStartElement()
8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 * so we need to remember the name
8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 */
8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_elemContext.m_elementName = name;
8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_elemContext.m_elementDesc = elemDesc;
8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return;
8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                elemContext = elemContext.push(namespaceURI,localName,name);
8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_elemContext = elemContext;
8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                elemContext.m_elementDesc = elemDesc;
8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                elemContext.m_isRaw = (elemFlags & ElemDesc.RAW) != 0;
8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((elemFlags & ElemDesc.HEADELEM) != 0)
8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // This is the <HEAD> element, do some special processing
8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                closeStartTag();
8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                elemContext.m_startTagOpen = false;
8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (!m_omitMetaTag)
9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (m_doIndent)
9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        indent();
9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(
9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        "<META http-equiv=\"Content-Type\" content=\"text/html; charset=");
9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String encoding = getEncoding();
9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String encode = Encodings.getMimeEncoding(encoding);
9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(encode);
9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write("\">");
9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        catch (IOException e)
9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throw new SAXException(e);
9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  Receive notification of the end of an element.
9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param namespaceURI
9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param localName
9249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param name The element type name
9259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @throws org.xml.sax.SAXException Any SAX exception, possibly
9269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *             wrapping another exception.
9279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final void endElement(
9299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final String namespaceURI,
9309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final String localName,
9319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final String name)
9329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws org.xml.sax.SAXException
9339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // deal with any pending issues
9359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_cdataTagOpen)
9369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            closeCDATA();
9379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // if the element has a namespace, treat it like XML, not HTML
9399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null != namespaceURI && namespaceURI.length() > 0)
9409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
9419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            super.endElement(namespaceURI, localName, name);
9429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return;
9449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        try
9479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
9489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            ElemContext elemContext = m_elemContext;
9509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final ElemDesc elemDesc = elemContext.m_elementDesc;
9519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final int elemFlags = elemDesc.getFlags();
9529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final boolean elemEmpty = (elemFlags & ElemDesc.EMPTY) != 0;
9539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // deal with any indentation issues
9559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_doIndent)
9569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
9579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                final boolean isBlockElement = (elemFlags&ElemDesc.BLOCK) != 0;
9589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                boolean shouldIndent = false;
9599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (m_ispreserve)
9619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
9629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_ispreserve = false;
9639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
9649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else if (m_doIndent && (!m_inBlockElem || isBlockElement))
9659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
9669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_startNewLine = true;
9679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    shouldIndent = true;
9689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
9699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (!elemContext.m_startTagOpen && shouldIndent)
9709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    indent(elemContext.m_currentElemDepth - 1);
9719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_inBlockElem = !isBlockElement;
9729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
9739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final java.io.Writer writer = m_writer;
9759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (!elemContext.m_startTagOpen)
9769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
9779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write("</");
9789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(name);
9799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write('>');
9809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
9819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
9829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
9839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // the start-tag open when this method was called,
9849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // so we need to process it now.
9859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (m_tracer != null)
9879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    super.fireStartElem(name);
9889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // the starting tag was still open when we received this endElement() call
9909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // so we need to process any gathered attributes NOW, before they go away.
9919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                int nAttrs = m_attributes.getLength();
9929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (nAttrs > 0)
9939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
9949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    processAttributes(m_writer, nAttrs);
9959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // clear attributes object for re-use with next element
9969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_attributes.clear();
9979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
9989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (!elemEmpty)
9999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
10009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // As per Dave/Paul recommendation 12/06/2000
10019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // if (shouldIndent)
10029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // writer.write('>');
10039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //  indent(m_currentIndent);
10049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write("></");
10069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(name);
10079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write('>');
10089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
10099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else
10109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
10119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write('>');
10129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
10139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // clean up because the element has ended
10169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((elemFlags & ElemDesc.WHITESPACESENSITIVE) != 0)
10179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_ispreserve = true;
10189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_isprevtext = false;
10199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // fire off the end element event
10219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_tracer != null)
10229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                super.fireEndElem(name);
10239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // OPTIMIZE-EMPTY
10259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (elemEmpty)
10269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
10279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // a quick exit if the HTML element had no children.
10289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // This block of code can be removed if the corresponding block of code
10299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // in startElement() also labeled with "OPTIMIZE-EMPTY" is also removed
10309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_elemContext = elemContext.m_prev;
10319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return;
10329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // some more clean because the element has ended.
10359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (!elemContext.m_startTagOpen)
10369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
10379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (m_doIndent && !m_preserves.isEmpty())
10389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_preserves.pop();
10399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
10409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_elemContext = elemContext.m_prev;
10419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//            m_isRawStack.pop();
10429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        catch (IOException e)
10449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
10459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throw new SAXException(e);
10469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Process an attribute.
10519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param   writer The writer to write the processed output to.
10529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param   name   The name of the attribute.
10539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param   value   The value of the attribute.
10549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param   elemDesc The description of the HTML element
10559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *           that has this attribute.
10569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
10579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
10589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void processAttribute(
10609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        java.io.Writer writer,
10619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String name,
10629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String value,
10639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ElemDesc elemDesc)
10649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws IOException
10659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        writer.write(' ');
10679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (   ((value.length() == 0) || value.equalsIgnoreCase(name))
10699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            && elemDesc != null
10709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            && elemDesc.isAttrFlagSet(name, ElemDesc.ATTREMPTY))
10719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
10729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write(name);
10739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
10759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
10769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // %REVIEW% %OPT%
10779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Two calls to single-char write may NOT
10789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // be more efficient than one to string-write...
10799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write(name);
10809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write("=\"");
10819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (   elemDesc != null
10829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                && elemDesc.isAttrFlagSet(name, ElemDesc.ATTRURL))
10839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writeAttrURI(writer, value, m_specialEscapeURLs);
10849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
10859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writeAttrString(writer, value, this.getEncoding());
10869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write('"');
10879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tell if a character is an ASCII digit.
10939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private boolean isASCIIDigit(char c)
10959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return (c >= '0' && c <= '9');
10979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Make an integer into an HH hex value.
11019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Does no checking on the size of the input, since this
11029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * is only meant to be used locally by writeAttrURI.
11039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param i must be a value less than 255.
11059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return should be a two character string.
11079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private static String makeHHString(int i)
11099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String s = Integer.toHexString(i).toUpperCase();
11119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (s.length() == 1)
11129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
11139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            s = "0" + s;
11149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
11159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return s;
11169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * Dmitri Ilyin: Makes sure if the String is HH encoded sign.
11209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * @param str must be 2 characters long
11219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    *
11229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * @return true or false
11239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    */
11249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private boolean isHHSign(String str)
11259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        boolean sign = true;
11279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        try
11289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
11299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            char r = (char) Integer.parseInt(str, 16);
11309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
11319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        catch (NumberFormatException e)
11329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
11339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            sign = false;
11349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
11359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return sign;
11369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Write the specified <var>string</var> after substituting non ASCII characters,
11409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * with <CODE>%HH</CODE>, where HH is the hex of the byte value.
11419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param   string      String to convert to XML format.
11439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param doURLEscaping True if we should try to encode as
11449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *                      per http://www.ietf.org/rfc/rfc2396.txt.
11459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
11469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException if a bad surrogate pair is detected.
11479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void writeAttrURI(
11499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final java.io.Writer writer, String string, boolean doURLEscaping)
11509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws IOException
11519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // http://www.ietf.org/rfc/rfc2396.txt says:
11539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // A URI is always in an "escaped" form, since escaping or unescaping a
11549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // completed URI might change its semantics.  Normally, the only time
11559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // escape encodings can safely be made is when the URI is being created
11569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // from its component parts; each component may have its own set of
11579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // characters that are reserved, so only the mechanism responsible for
11589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // generating or interpreting that component can determine whether or
11599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // not escaping a character will change its semantics. Likewise, a URI
11609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // must be separated into its components before the escaped characters
11619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // within those components can be safely decoded.
11629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //
11639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // ...So we do our best to do limited escaping of the URL, without
11649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // causing damage.  If the URL is already properly escaped, in theory, this
11659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // function should not change the string value.
11669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final int end = string.length();
11689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (end > m_attrBuff.length)
11699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
11709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           m_attrBuff = new char[end*2 + 1];
11719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
11729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        string.getChars(0,end, m_attrBuff, 0);
11739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final char[] chars = m_attrBuff;
11749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int cleanStart = 0;
11769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int cleanLength = 0;
11779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        char ch = 0;
11809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (int i = 0; i < end; i++)
11819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
11829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            ch = chars[i];
11839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((ch < 32) || (ch > 126))
11859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
11869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (cleanLength > 0)
11879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
11889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(chars, cleanStart, cleanLength);
11899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    cleanLength = 0;
11909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
11919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (doURLEscaping)
11929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
11939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // Encode UTF16 to UTF8.
11949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // Reference is Unicode, A Primer, by Tony Graham.
11959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // Page 92.
11969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // Note that Kay doesn't escape 0x20...
11989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //  if(ch == 0x20) // Not sure about this... -sb
11999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //  {
12009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //    writer.write(ch);
12019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //  }
12029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //  else
12039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (ch <= 0x7F)
12049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
12059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write('%');
12069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(makeHHString(ch));
12079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
12089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    else if (ch <= 0x7FF)
12099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
12109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // Clear low 6 bits before rotate, put high 4 bits in low byte,
12119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // and set two high bits.
12129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int high = (ch >> 6) | 0xC0;
12139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int low = (ch & 0x3F) | 0x80;
12149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // First 6 bits, + high bit
12159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write('%');
12169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(makeHHString(high));
12179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write('%');
12189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(makeHHString(low));
12199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
12209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    else if (Encodings.isHighUTF16Surrogate(ch)) // high surrogate
12219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
12229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // I'm sure this can be done in 3 instructions, but I choose
12239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // to try and do it exactly like it is done in the book, at least
12249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // until we are sure this is totally clean.  I don't think performance
12259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // is a big issue with this particular function, though I could be
12269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // wrong.  Also, the stuff below clearly does more masking than
12279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // it needs to do.
12289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // Clear high 6 bits.
12309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int highSurrogate = ((int) ch) & 0x03FF;
12319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // Middle 4 bits (wwww) + 1
12339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // "Note that the value of wwww from the high surrogate bit pattern
12349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // is incremented to make the uuuuu bit pattern in the scalar value
12359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // so the surrogate pair don't address the BMP."
12369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int wwww = ((highSurrogate & 0x03C0) >> 6);
12379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int uuuuu = wwww + 1;
12389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // next 4 bits
12409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int zzzz = (highSurrogate & 0x003C) >> 2;
12419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // low 2 bits
12439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int yyyyyy = ((highSurrogate & 0x0003) << 4) & 0x30;
12449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // Get low surrogate character.
12469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        ch = chars[++i];
12479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // Clear high 6 bits.
12499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int lowSurrogate = ((int) ch) & 0x03FF;
12509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // put the middle 4 bits into the bottom of yyyyyy (byte 3)
12529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        yyyyyy = yyyyyy | ((lowSurrogate & 0x03C0) >> 6);
12539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // bottom 6 bits.
12559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int xxxxxx = (lowSurrogate & 0x003F);
12569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int byte1 = 0xF0 | (uuuuu >> 2); // top 3 bits of uuuuu
12589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int byte2 =
12599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            0x80 | (((uuuuu & 0x03) << 4) & 0x30) | zzzz;
12609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int byte3 = 0x80 | yyyyyy;
12619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int byte4 = 0x80 | xxxxxx;
12629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write('%');
12649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(makeHHString(byte1));
12659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write('%');
12669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(makeHHString(byte2));
12679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write('%');
12689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(makeHHString(byte3));
12699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write('%');
12709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(makeHHString(byte4));
12719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
12729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    else
12739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
12749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int high = (ch >> 12) | 0xE0; // top 4 bits
12759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int middle = ((ch & 0x0FC0) >> 6) | 0x80;
12769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // middle 6 bits
12779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        int low = (ch & 0x3F) | 0x80;
12789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        // First 6 bits, + high bit
12799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write('%');
12809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(makeHHString(high));
12819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write('%');
12829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(makeHHString(middle));
12839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write('%');
12849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(makeHHString(low));
12859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
12869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
12889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else if (escapingNotNeeded(ch))
12899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
12909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(ch);
12919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
12929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else
12939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
12949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write("&#");
12959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(Integer.toString(ch));
12969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(';');
12979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
12989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // In this character range we have first written out any previously accumulated
12999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // "clean" characters, then processed the current more complicated character,
13009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // which may have incremented "i".
13019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // We now we reset the next possible clean character.
13029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                cleanStart = i + 1;
13039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
13049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Since http://www.ietf.org/rfc/rfc2396.txt refers to the URI grammar as
13059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // not allowing quotes in the URI proper syntax, nor in the fragment
13069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // identifier, we believe that it's OK to double escape quotes.
13079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else if (ch == '"')
13089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
13099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // If the character is a '%' number number, try to avoid double-escaping.
13109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // There is a question if this is legal behavior.
13119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // Dmitri Ilyin: to check if '%' number number is invalid. It must be checked if %xx is a sign, that would be encoded
13139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // The encoded signes are in Hex form. So %xx my be in form %3C that is "<" sign. I will try to change here a little.
13149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                //        if( ((i+2) < len) && isASCIIDigit(stringArray[i+1]) && isASCIIDigit(stringArray[i+2]) )
13169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // We are no longer escaping '%'
13189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (cleanLength > 0)
13209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
13219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(chars, cleanStart, cleanLength);
13229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    cleanLength = 0;
13239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
13249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // Mike Kay encodes this as &#34;, so he may know something I don't?
13279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (doURLEscaping)
13289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write("%22");
13299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else
13309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write("&quot;"); // we have to escape this, I guess.
13319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // We have written out any clean characters, then the escaped '%' and now we
13339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // We now we reset the next possible clean character.
13349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                cleanStart = i + 1;
13359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
13369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else if (ch == '&')
13379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
13389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // HTML 4.01 reads, "Authors should use "&amp;" (ASCII decimal 38)
13399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // instead of "&" to avoid confusion with the beginning of a character
13409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // reference (entity reference open delimiter).
13419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (cleanLength > 0)
13429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
13439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(chars, cleanStart, cleanLength);
13449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    cleanLength = 0;
13459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
13469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write("&amp;");
13479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                cleanStart = i + 1;
13489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
13499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
13509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
13519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // no processing for this character, just count how
13529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // many characters in a row that we have that need no processing
13539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                cleanLength++;
13549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
13559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
13569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // are there any clean characters at the end of the array
13589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // that we haven't processed yet?
13599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (cleanLength > 1)
13609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
13619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // if the whole string can be written out as-is do so
13629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // otherwise write out the clean chars at the end of the
13639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // array
13649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (cleanStart == 0)
13659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(string);
13669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
13679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(chars, cleanStart, cleanLength);
13689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
13699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (cleanLength == 1)
13709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
13719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // a little optimization for 1 clean character
13729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // (we could have let the previous if(...) handle them all)
13739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write(ch);
13749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
13759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
13789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Writes the specified <var>string</var> after substituting <VAR>specials</VAR>,
13799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * and UTF-16 surrogates for character references <CODE>&amp;#xnn</CODE>.
13809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param   string      String to convert to XML format.
13829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param   encoding    CURRENTLY NOT IMPLEMENTED.
13839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
13849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
13859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
13869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void writeAttrString(
13879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final java.io.Writer writer, String string, String encoding)
13889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws IOException
13899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final int end = string.length();
13919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (end > m_attrBuff.length)
13929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
13939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_attrBuff = new char[end * 2 + 1];
13949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
13959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        string.getChars(0, end, m_attrBuff, 0);
13969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final char[] chars = m_attrBuff;
13979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int cleanStart = 0;
14019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int cleanLength = 0;
14029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        char ch = 0;
14049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (int i = 0; i < end; i++)
14059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
14069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            ch = chars[i];
14079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // System.out.println("SPECIALSSIZE: "+SPECIALSSIZE);
14099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // System.out.println("ch: "+(int)ch);
14109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // System.out.println("m_maxCharacter: "+(int)m_maxCharacter);
14119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // System.out.println("m_attrCharsMap[ch]: "+(int)m_attrCharsMap[ch]);
14129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (escapingNotNeeded(ch) && (!m_charInfo.shouldMapAttrChar(ch)))
14139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
14149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                cleanLength++;
14159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
14169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else if ('<' == ch || '>' == ch)
14179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
14189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                cleanLength++; // no escaping in this case, as specified in 15.2
14199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
14209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else if (
14219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                ('&' == ch) && ((i + 1) < end) && ('{' == chars[i + 1]))
14229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
14239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                cleanLength++; // no escaping in this case, as specified in 15.2
14249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
14259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
14269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
14279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (cleanLength > 0)
14289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
14299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(chars,cleanStart,cleanLength);
14309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    cleanLength = 0;
14319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
14329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                int pos = accumDefaultEntity(writer, ch, i, chars, end, false, true);
14339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (i != pos)
14359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
14369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    i = pos - 1;
14379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
14389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else
14399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
14409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (Encodings.isHighUTF16Surrogate(ch))
14419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
14429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            writeUTF16Surrogate(ch, chars, i, end);
14449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            i++; // two input characters processed
14459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                 // this increments by one and the for()
14469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                 // loop itself increments by another one.
14479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
14489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // The next is kind of a hack to keep from escaping in the case
14509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // of Shift_JIS and the like.
14519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    /*
14539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    else if ((ch < m_maxCharacter) && (m_maxCharacter == 0xFFFF)
14549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    && (ch != 160))
14559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
14569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer.write(ch);  // no escaping in this case
14579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
14589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    else
14599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    */
14609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    String outputStringForChar = m_charInfo.getOutputStringForChar(ch);
14619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    if (null != outputStringForChar)
14629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
14639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(outputStringForChar);
14649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
14659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    else if (escapingNotNeeded(ch))
14669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
14679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(ch); // no escaping in this case
14689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
14699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    else
14709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
14719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write("&#");
14729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(Integer.toString(ch));
14739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        writer.write(';');
14749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
14759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
14769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                cleanStart = i + 1;
14779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
14789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } // end of for()
14799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // are there any clean characters at the end of the array
14819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // that we haven't processed yet?
14829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (cleanLength > 1)
14839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
14849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // if the whole string can be written out as-is do so
14859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // otherwise write out the clean chars at the end of the
14869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // array
14879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (cleanStart == 0)
14889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(string);
14899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
14909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(chars, cleanStart, cleanLength);
14919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (cleanLength == 1)
14939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
14949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // a little optimization for 1 clean character
14959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // (we could have let the previous if(...) handle them all)
14969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write(ch);
14979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
14989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Receive notification of character data.
15049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>The Parser will call this method to report each chunk of
15069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * character data.  SAX parsers may return all contiguous character
15079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * data in a single chunk, or they may split it into several
15089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * chunks; however, all of the characters in any single event
15099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * must come from the same external entity, so that the Locator
15109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * provides useful information.</p>
15119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>The application must not attempt to read from the array
15139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * outside of the specified range.</p>
15149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <p>Note that some parsers will report whitespace using the
15169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * ignorableWhitespace() method rather than this one (validating
15179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * parsers must do so).</p>
15189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param chars The characters from the XML document.
15209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param start The start position in the array.
15219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param length The number of characters to read from the array.
15229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException Any SAX exception, possibly
15239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *            wrapping another exception.
15249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see #ignorableWhitespace
15259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see org.xml.sax.Locator
15269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
15289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final void characters(char chars[], int start, int length)
15309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws org.xml.sax.SAXException
15319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_elemContext.m_isRaw)
15349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
15359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            try
15369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
15379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // Clean up some pending issues.
15389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (m_elemContext.m_startTagOpen)
15399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
15409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    closeStartTag();
15419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_elemContext.m_startTagOpen = false;
15429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
15439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_ispreserve = true;
15459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writeNormalizedChars(chars, start, length, false, m_lineSepUse);
15479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // time to generate characters event
15499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (m_tracer != null)
15509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    super.fireCharEvent(chars, start, length);
15519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return;
15539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
15549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            catch (IOException ioe)
15559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
15569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                throw new org.xml.sax.SAXException(
15579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    Utils.messages.createMessage(MsgKey.ER_OIERROR,null),ioe);
15589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
15599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
15609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
15619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
15629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            super.characters(chars, start, length);
15639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
15649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
15679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  Receive notification of cdata.
15689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  <p>The Parser will call this method to report each chunk of
15709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  character data.  SAX parsers may return all contiguous character
15719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  data in a single chunk, or they may split it into several
15729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  chunks; however, all of the characters in any single event
15739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  must come from the same external entity, so that the Locator
15749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  provides useful information.</p>
15759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  <p>The application must not attempt to read from the array
15779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  outside of the specified range.</p>
15789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  <p>Note that some parsers will report whitespace using the
15809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  ignorableWhitespace() method rather than this one (validating
15819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  parsers must do so).</p>
15829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param ch The characters from the XML document.
15849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param start The start position in the array.
15859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param length The number of characters to read from the array.
15869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @throws org.xml.sax.SAXException Any SAX exception, possibly
15879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *             wrapping another exception.
15889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @see #ignorableWhitespace
15899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @see org.xml.sax.Locator
15909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
15919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
15929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
15939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final void cdata(char ch[], int start, int length)
15949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws org.xml.sax.SAXException
15959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((null != m_elemContext.m_elementName)
15989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            && (m_elemContext.m_elementName.equalsIgnoreCase("SCRIPT")
15999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                || m_elemContext.m_elementName.equalsIgnoreCase("STYLE")))
16009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
16019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            try
16029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
16039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (m_elemContext.m_startTagOpen)
16049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
16059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    closeStartTag();
16069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_elemContext.m_startTagOpen = false;
16079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
16089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_ispreserve = true;
16109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (shouldIndent())
16129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    indent();
16139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // writer.write(ch, start, length);
16159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writeNormalizedChars(ch, start, length, true, m_lineSepUse);
16169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
16179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            catch (IOException ioe)
16189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
16199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                throw new org.xml.sax.SAXException(
16209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    Utils.messages.createMessage(
16219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        MsgKey.ER_OIERROR,
16229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        null),
16239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    ioe);
16249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                //"IO error", ioe);
16259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
16269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
16289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
16299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            super.cdata(ch, start, length);
16309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
16349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  Receive notification of a processing instruction.
16359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param target The processing instruction target.
16379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @param data The processing instruction data, or null if
16389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *         none was supplied.
16399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *  @throws org.xml.sax.SAXException Any SAX exception, possibly
16409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *             wrapping another exception.
16419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
16429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
16439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
16449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void processingInstruction(String target, String data)
16459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws org.xml.sax.SAXException
16469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Process any pending starDocument and startElement first.
16499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        flushPending();
16509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Use a fairly nasty hack to tell if the next node is supposed to be
16529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // unescaped text.
16539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING))
16549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
16559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            startNonEscaping();
16569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (target.equals(Result.PI_ENABLE_OUTPUT_ESCAPING))
16589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
16599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            endNonEscaping();
16609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
16629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
16639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            try
16649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
16659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // clean up any pending things first
16669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (m_elemContext.m_startTagOpen)
16679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
16689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    closeStartTag();
16699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_elemContext.m_startTagOpen = false;
16709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
16719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else if (m_cdataTagOpen)
16729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
16739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    closeCDATA();
16749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
16759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else if (m_needToCallStartDocument)
16769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
16779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    startDocumentInternal();
16789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
16799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /*
16829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * Perhaps processing instructions can be written out in HTML before
16839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * the DOCTYPE, in which case this could be emitted with the
16849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * startElement call, that knows the name of the document element
16859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * doing it right.
16869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             */
16879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (true == m_needToOutputDocTypeDecl)
16889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                outputDocTypeDecl("html"); // best guess for the upcoming element
16899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (shouldIndent())
16929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                indent();
16939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final java.io.Writer writer = m_writer;
16959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            //writer.write("<?" + target);
16969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write("<?");
16979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write(target);
16989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (data.length() > 0 && !Character.isSpaceChar(data.charAt(0)))
17009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(' ');
17019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            //writer.write(data + ">"); // different from XML
17039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write(data); // different from XML
17049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            writer.write('>'); // different from XML
17059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Always output a newline char if not inside of an
17079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // element. The whitespace is not significant in that
17089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // case.
17099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_elemContext.m_currentElemDepth <= 0)
17109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                outputLineSep();
17119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_startNewLine = true;
17139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
17149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            catch(IOException e)
17159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
17169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                throw new SAXException(e);
17179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
17189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
17199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // now generate the PI event
17219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_tracer != null)
17229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            super.fireEscapingEvent(target, data);
17239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     }
17249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
17269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Receive notivication of a entityReference.
17279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param name non-null reference to entity name string.
17299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
17319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
17329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final void entityReference(String name)
17339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws org.xml.sax.SAXException
17349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
17359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        try
17369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
17379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final java.io.Writer writer = m_writer;
17399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        writer.write('&');
17409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        writer.write(name);
17419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        writer.write(';');
17429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } catch(IOException e)
17449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
17459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throw new SAXException(e);
17469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
17479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
17499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see ExtendedContentHandler#endElement(String)
17509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
17519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final void endElement(String elemName) throws SAXException
17529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
17539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        endElement(null, null, elemName);
17549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
17579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Process the attributes, which means to write out the currently
17589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * collected attributes to the writer. The attributes are not
17599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * cleared by this method
17609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param writer the writer to write processed attributes to.
17629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param nAttrs the number of attributes in m_attributes
17639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * to be processed
17649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException
17669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
17679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void processAttributes(java.io.Writer writer, int nAttrs)
17689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws IOException,SAXException
17699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
17709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /*
17719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * process the collected attributes
17729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             */
17739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            for (int i = 0; i < nAttrs; i++)
17749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
17759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                processAttribute(
17769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writer,
17779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_attributes.getQName(i),
17789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_attributes.getValue(i),
17799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_elemContext.m_elementDesc);
17809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
17819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
17849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * For the enclosing elements starting tag write out out any attributes
17859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * followed by ">". At this point we also mark if this element is
17869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * a cdata-section-element.
17879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
17889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *@throws org.xml.sax.SAXException
17899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
17909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected void closeStartTag() throws SAXException
17919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
17929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            try
17939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
17949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // finish processing attributes, time to fire off the start element event
17969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_tracer != null)
17979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                super.fireStartElem(m_elemContext.m_elementName);
17989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int nAttrs = m_attributes.getLength();
18009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (nAttrs>0)
18019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
18029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                processAttributes(m_writer, nAttrs);
18039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // clear attributes object for re-use with next element
18049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_attributes.clear();
18059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
18069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_writer.write('>');
18089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /* At this point we have the prefix mappings now, so
18109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * lets determine if the current element is specified in the cdata-
18119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * section-elements list.
18129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             */
18139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_CdataElems != null) // if there are any cdata sections
18149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_elemContext.m_isCdataSection = isCdataSection();
18159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_doIndent)
18169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
18179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_isprevtext = false;
18189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_preserves.push(m_ispreserve);
18199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
18209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
18229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            catch(IOException e)
18239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
18249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                throw new SAXException(e);
18259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
18269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
18279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
18319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * This method is used when a prefix/uri namespace mapping
18329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * is indicated after the element was started with a
18339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * startElement() and before and endElement().
18349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * startPrefixMapping(prefix,uri) would be used before the
18359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * startElement() call.
18369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @param uri the URI of the namespace
18379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @param prefix the prefix associated with the given URI.
18389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
18399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @see ExtendedContentHandler#namespaceAfterStartElement(String, String)
18409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
18419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        public void namespaceAfterStartElement(String prefix, String uri)
18429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws SAXException
18439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
18449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // hack for XSLTC with finding URI for default namespace
18459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_elemContext.m_elementURI == null)
18469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
18479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                String prefix1 = getPrefixPart(m_elemContext.m_elementName);
18489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (prefix1 == null && EMPTYSTRING.equals(prefix))
18499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
18509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // the elements URI is not known yet, and it
18519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // doesn't have a prefix, and we are currently
18529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // setting the uri for prefix "", so we have
18539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    // the uri for the element... lets remember it
18549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    m_elemContext.m_elementURI = uri;
18559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
18569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
18579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            startPrefixMapping(prefix,uri,false);
18589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
18599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void startDTD(String name, String publicId, String systemId)
18619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException
18629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
18639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_inDTD = true;
18649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        super.startDTD(name, publicId, systemId);
18659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
18669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
18689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Report the end of DTD declarations.
18699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws org.xml.sax.SAXException The application may raise an exception.
18709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see #startDTD
18719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
18729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void endDTD() throws org.xml.sax.SAXException
18739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
18749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_inDTD = false;
18759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /* for ToHTMLStream the DOCTYPE is entirely output in the
18769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * startDocumentInternal() method, so don't do anything here
18779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
18789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
18799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
18809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method does nothing.
18819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
18829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void attributeDecl(
18839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String eName,
18849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String aName,
18859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String type,
18869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String valueDefault,
18879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String value)
18889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException
18899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
18909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // The internal DTD subset is not serialized by the ToHTMLStream serializer
18919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
18929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
18949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method does nothing.
18959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
18969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void elementDecl(String name, String model) throws SAXException
18979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
18989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // The internal DTD subset is not serialized by the ToHTMLStream serializer
18999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
19009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
19019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method does nothing.
19029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
19039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void internalEntityDecl(String name, String value)
19049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException
19059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
19069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // The internal DTD subset is not serialized by the ToHTMLStream serializer
19079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
19089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
19099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method does nothing.
19109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
19119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void externalEntityDecl(
19129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String name,
19139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String publicId,
19149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String systemId)
19159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException
19169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
19179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // The internal DTD subset is not serialized by the ToHTMLStream serializer
19189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
19199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
19219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method is used to add an attribute to the currently open element.
19229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * The caller has guaranted that this attribute is unique, which means that it
19239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * not been seen before and will not be seen again.
19249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
19259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param name the qualified name of the attribute
19269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param value the value of the attribute which can contain only
19279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * ASCII printable characters characters in the range 32 to 127 inclusive.
19289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param flags the bit values of this integer give optimization information.
19299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
19309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void addUniqueAttribute(String name, String value, int flags)
19319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throws SAXException
19329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
19339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        try
19349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
19359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final java.io.Writer writer = m_writer;
19369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if ((flags & NO_BAD_CHARS) > 0 && m_htmlcharInfo.onlyQuotAmpLtGt)
19379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
19389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // "flags" has indicated that the characters
19399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // '>'  '<'   '&'  and '"' are not in the value and
19409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // m_htmlcharInfo has recorded that there are no other
19419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // entities in the range 0 to 127 so we write out the
19429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // value directly
19439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(' ');
19449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(name);
19459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write("=\"");
19469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(value);
19479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write('"');
19489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
19499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else if (
19509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                (flags & HTML_ATTREMPTY) > 0
19519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    && (value.length() == 0 || value.equalsIgnoreCase(name)))
19529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
19539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(' ');
19549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(name);
19559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
19569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
19579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
19589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(' ');
19599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write(name);
19609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write("=\"");
19619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if ((flags & HTML_ATTRURL) > 0)
19629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
19639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writeAttrURI(writer, value, m_specialEscapeURLs);
19649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
19659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else
19669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
19679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    writeAttrString(writer, value, this.getEncoding());
19689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
19699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                writer.write('"');
19709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
19719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } catch (IOException e) {
19729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throw new SAXException(e);
19739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
19749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
19759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void comment(char ch[], int start, int length)
19779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws SAXException
19789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
19799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // The internal DTD subset is not serialized by the ToHTMLStream serializer
19809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_inDTD)
19819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return;
19829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Clean up some pending issues, just in case
19849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // this call is coming right after a startElement()
19859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // or we are in the middle of writing out CDATA
19869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // or if a startDocument() call was not received
19879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_elemContext.m_startTagOpen)
19889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
19899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            closeStartTag();
19909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_elemContext.m_startTagOpen = false;
19919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
19929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (m_cdataTagOpen)
19939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
19949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            closeCDATA();
19959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
19969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (m_needToCallStartDocument)
19979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
19989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            startDocumentInternal();
19999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
20009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /*
20029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Perhaps comments can be written out in HTML before the DOCTYPE.
20039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * In this case we might delete this call to writeOutDOCTYPE, and
20049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * it would be handled within the startElement() call.
20059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
20069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_needToOutputDocTypeDecl)
20079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            outputDocTypeDecl("html"); // best guess for the upcoming element
20089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        super.comment(ch, start, length);
20109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
20119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public boolean reset()
20139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
20149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        boolean ret = super.reset();
20159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!ret)
20169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return false;
20179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        resetToHTMLStream();
20189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return true;
20199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
20209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private void resetToHTMLStream()
20229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
20239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // m_htmlcharInfo remains unchanged
20249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // m_htmlInfo = null;  // Don't reset
20259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_inBlockElem = false;
20269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_inDTD = false;
20279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_omitMetaTag = false;
20289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_specialEscapeURLs = true;
20299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
20309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static class Trie
20329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
20339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
20349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * A digital search trie for 7-bit ASCII text
20359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * The API is a subset of java.util.Hashtable
20369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * The key must be a 7-bit ASCII string
20379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * The value may be any Java Object
20389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * One can get an object stored in a trie from its key,
20399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * but the search is either case sensitive or case
20409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * insensitive to the characters in the key, and this
20419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * choice of sensitivity or insensitivity is made when
20429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * the Trie is created, before any objects are put in it.
20439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
20449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * This class is a copy of the one in org.apache.xml.utils.
20459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * It exists to cut the serializers dependancy on that package.
20469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
20479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @xsl.usage internal
20489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
20499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /** Size of the m_nextChar array.  */
20519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        public static final int ALPHA_SIZE = 128;
20529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /** The root node of the tree.    */
20549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        final Node m_Root;
20559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /** helper buffer to convert Strings to char arrays */
20579fb03df8f04136e01e1c54ce55b5f14f19e6af98Anatol Pomazau        private char[] m_charBuffer = new char[0];
20589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /** true if the search for an object is lower case only with the key */
20609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private final boolean m_lowerCaseOnly;
20619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
20639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Construct the trie that has a case insensitive search.
20649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
20659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        public Trie()
20669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
20679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_Root = new Node();
20689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_lowerCaseOnly = false;
20699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
20709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
20729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Construct the trie given the desired case sensitivity with the key.
20739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @param lowerCaseOnly true if the search keys are to be loser case only,
20749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * not case insensitive.
20759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
20769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        public Trie(boolean lowerCaseOnly)
20779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
20789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_Root = new Node();
20799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_lowerCaseOnly = lowerCaseOnly;
20809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
20819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
20839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Put an object into the trie for lookup.
20849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
20859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @param key must be a 7-bit ASCII string
20869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @param value any java object.
20879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
20889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @return The old object that matched key, or null.
20899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
20909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        public Object put(String key, Object value)
20919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
20929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final int len = key.length();
20949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (len > m_charBuffer.length)
20959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
20969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // make the biggest buffer ever needed in get(String)
20979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_charBuffer = new char[len];
20989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
20999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Node node = m_Root;
21019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            for (int i = 0; i < len; i++)
21039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
21049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                Node nextNode =
21059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    node.m_nextChar[Character.toLowerCase(key.charAt(i))];
21069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (nextNode != null)
21089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
21099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    node = nextNode;
21109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
21119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else
21129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
21139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    for (; i < len; i++)
21149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
21159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        Node newNode = new Node();
21169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (m_lowerCaseOnly)
21179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        {
21189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            // put this value into the tree only with a lower case key
21199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            node.m_nextChar[Character.toLowerCase(
21209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                key.charAt(i))] =
21219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                newNode;
21229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
21239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        else
21249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        {
21259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            // put this value into the tree with a case insensitive key
21269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            node.m_nextChar[Character.toUpperCase(
21279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                key.charAt(i))] =
21289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                newNode;
21299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            node.m_nextChar[Character.toLowerCase(
21309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                key.charAt(i))] =
21319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                newNode;
21329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
21339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        node = newNode;
21349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
21359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    break;
21369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
21379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
21389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Object ret = node.m_Value;
21409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            node.m_Value = value;
21429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return ret;
21449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
21459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
21479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Get an object that matches the key.
21489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
21499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @param key must be a 7-bit ASCII string
21509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
21519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @return The object that matches the key, or null.
21529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
21539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        public Object get(final String key)
21549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
21559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final int len = key.length();
21579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /* If the name is too long, we won't find it, this also keeps us
21599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * from overflowing m_charBuffer
21609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             */
21619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_charBuffer.length < len)
21629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return null;
21639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Node node = m_Root;
21659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            switch (len) // optimize the look up based on the number of chars
21669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
21679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // case 0 looks silly, but the generated bytecode runs
21689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // faster for lookup of elements of length 2 with this in
21699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // and a fair bit faster.  Don't know why.
21709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                case 0 :
21719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
21729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        return null;
21739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
21749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                case 1 :
21769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
21779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        final char ch = key.charAt(0);
21789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (ch < ALPHA_SIZE)
21799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        {
21809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            node = node.m_nextChar[ch];
21819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            if (node != null)
21829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                return node.m_Value;
21839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
21849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        return null;
21859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
21869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                comment out case 2 because the default is faster
21879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                case 2 :
21889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                    {
21899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                        final char ch0 = key.charAt(0);
21909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                        final char ch1 = key.charAt(1);
21919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                        if (ch0 < ALPHA_SIZE && ch1 < ALPHA_SIZE)
21929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                        {
21939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                            node = node.m_nextChar[ch0];
21949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                            if (node != null)
21959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                            {
21969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //
21979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                                if (ch1 < ALPHA_SIZE)
21989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                                {
21999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                                    node = node.m_nextChar[ch1];
22009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                                    if (node != null)
22019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                                        return node.m_Value;
22029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                                }
22039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                            }
22049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                        }
22059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                        return null;
22069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    //                   }
22079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                default :
22089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
22099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        for (int i = 0; i < len; i++)
22109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        {
22119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            // A thread-safe way to loop over the characters
22129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            final char ch = key.charAt(i);
22139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            if (ALPHA_SIZE <= ch)
22149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            {
22159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                // the key is not 7-bit ASCII so we won't find it here
22169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                return null;
22179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            }
22189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            node = node.m_nextChar[ch];
22209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            if (node == null)
22219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                return null;
22229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
22239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        return node.m_Value;
22259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
22269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
22279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
22289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
22309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * The node representation for the trie.
22319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @xsl.usage internal
22329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
22339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private class Node
22349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
22359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /**
22379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * Constructor, creates a Node[ALPHA_SIZE].
22389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             */
22399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Node()
22409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
22419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_nextChar = new Node[ALPHA_SIZE];
22429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_Value = null;
22439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
22449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /** The next nodes.   */
22469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final Node m_nextChar[];
22479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /** The value.   */
22499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Object m_Value;
22509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
22519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
22529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Construct the trie from another Trie.
22539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Both the existing Trie and this new one share the same table for
22549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * lookup, and it is assumed that the table is fully populated and
22559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * not changing anymore.
22569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
22579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @param existingTrie the Trie that this one is a copy of.
22589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
22599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        public Trie(Trie existingTrie)
22609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
22619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // copy some fields from the existing Trie into this one.
22629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_Root = existingTrie.m_Root;
22639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_lowerCaseOnly = existingTrie.m_lowerCaseOnly;
22649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // get a buffer just big enough to hold the longest key in the table.
22669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int max = existingTrie.getLongestKeyLength();
22679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_charBuffer = new char[max];
22689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
22699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
22719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Get an object that matches the key.
22729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * This method is faster than get(), but is not thread-safe.
22739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
22749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @param key must be a 7-bit ASCII string
22759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
22769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @return The object that matches the key, or null.
22779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
22789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        public Object get2(final String key)
22799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
22809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final int len = key.length();
22829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /* If the name is too long, we won't find it, this also keeps us
22849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * from overflowing m_charBuffer
22859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             */
22869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_charBuffer.length < len)
22879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return null;
22889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
22899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Node node = m_Root;
22909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            switch (len) // optimize the look up based on the number of chars
22919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
22929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // case 0 looks silly, but the generated bytecode runs
22939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // faster for lookup of elements of length 2 with this in
22949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // and a fair bit faster.  Don't know why.
22959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                case 0 :
22969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
22979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        return null;
22989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
22999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                case 1 :
23019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
23029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        final char ch = key.charAt(0);
23039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        if (ch < ALPHA_SIZE)
23049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        {
23059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            node = node.m_nextChar[ch];
23069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            if (node != null)
23079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                return node.m_Value;
23089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
23099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        return null;
23109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
23119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                default :
23129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    {
23139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        /* Copy string into array. This is not thread-safe because
23149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                         * it modifies the contents of m_charBuffer. If multiple
23159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                         * threads were to use this Trie they all would be
23169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                         * using this same array (not good). So this
23179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                         * method is not thread-safe, but it is faster because
23189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                         * converting to a char[] and looping over elements of
23199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                         * the array is faster than a String's charAt(i).
23209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                         */
23219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        key.getChars(0, len, m_charBuffer, 0);
23229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        for (int i = 0; i < len; i++)
23249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        {
23259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            final char ch = m_charBuffer[i];
23269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            if (ALPHA_SIZE <= ch)
23279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            {
23289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                // the key is not 7-bit ASCII so we won't find it here
23299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                return null;
23309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            }
23319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            node = node.m_nextChar[ch];
23339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            if (node == null)
23349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                return null;
23359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        }
23369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        return node.m_Value;
23389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    }
23399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
23409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
23419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
23429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
23439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Get the length of the longest key used in the table.
23449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
23459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        public int getLongestKeyLength()
23469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
23479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return m_charBuffer.length;
23489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
23499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
23509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
2351