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: AttributesImplSerializer.java 468654 2006-10-28 07:09:23Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.serializer;
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Hashtable;
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.Attributes;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.helpers.AttributesImpl;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class extends org.xml.sax.helpers.AttributesImpl which implements org.
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * xml.sax.Attributes. But for optimization this class adds a Hashtable for
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * faster lookup of an index by qName, which is commonly done in the stream
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * serializer.
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @see org.xml.sax.Attributes
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage internal
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic final class AttributesImplSerializer extends AttributesImpl
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Hash table of qName/index values to quickly lookup the index
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * of an attributes qName.  qNames are in uppercase in the hash table
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * to make the search case insensitive.
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * The keys to the hashtable to find the index are either
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * "prefix:localName"  or "{uri}localName".
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final Hashtable m_indexFromQName = new Hashtable();
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private final StringBuffer m_buff = new StringBuffer();
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This is the number of attributes before switching to the hash table,
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * and can be tuned, but 12 seems good for now - Brian M.
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private static final int MAX = 12;
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * One less than the number of attributes before switching to
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the Hashtable.
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private static final int MAXMinus1 = MAX - 1;
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method gets the index of an attribute given its qName.
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param qname the qualified name of the attribute, e.g. "prefix1:locName1"
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the integer index of the attribute.
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see org.xml.sax.Attributes#getIndex(String)
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final int getIndex(String qname)
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int index;
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (super.getLength() < MAX)
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // if we haven't got too many attributes let the
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // super class look it up
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            index = super.getIndex(qname);
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return index;
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // we have too many attributes and the super class is slow
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // so find it quickly using our Hashtable.
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Integer i = (Integer)m_indexFromQName.get(qname);
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (i == null)
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            index = -1;
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            index = i.intValue();
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return index;
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method adds the attribute, but also records its qName/index pair in
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the hashtable for fast lookup by getIndex(qName).
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param uri the URI of the attribute
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param local the local name of the attribute
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param qname the qualified name of the attribute
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param type the type of the attribute
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param val the value of the attribute
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see org.xml.sax.helpers.AttributesImpl#addAttribute(String, String, String, String, String)
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see #getIndex(String)
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final void addAttribute(
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String uri,
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String local,
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String qname,
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String type,
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String val)
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int index = super.getLength();
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        super.addAttribute(uri, local, qname, type, val);
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // (index + 1) is now the number of attributes
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // so either compare (index+1) to MAX, or compare index to (MAX-1)
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (index < MAXMinus1)
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return;
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (index == MAXMinus1)
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            switchOverToHash(MAX);
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /* add the key with the format of "prefix:localName" */
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /* we have just added the attibute, its index is the old length */
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Integer i = new Integer(index);
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_indexFromQName.put(qname, i);
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /* now add with key of the format "{uri}localName" */
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_buff.setLength(0);
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_buff.append('{').append(uri).append('}').append(local);
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String key = m_buff.toString();
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_indexFromQName.put(key, i);
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return;
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * We are switching over to having a hash table for quick look
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * up of attributes, but up until now we haven't kept any
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * information in the Hashtable, so we now update the Hashtable.
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Future additional attributes will update the Hashtable as
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * they are added.
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param numAtts
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private void switchOverToHash(int numAtts)
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (int index = 0; index < numAtts; index++)
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String qName = super.getQName(index);
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            Integer i = new Integer(index);
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_indexFromQName.put(qName, i);
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Add quick look-up to find with uri/local name pair
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String uri = super.getURI(index);
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String local = super.getLocalName(index);
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_buff.setLength(0);
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_buff.append('{').append(uri).append('}').append(local);
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            String key = m_buff.toString();
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_indexFromQName.put(key, i);
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method clears the accumulated attributes.
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see org.xml.sax.helpers.AttributesImpl#clear()
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final void clear()
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int len = super.getLength();
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        super.clear();
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (MAX <= len)
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // if we have had enough attributes and are
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // using the Hashtable, then clear the Hashtable too.
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_indexFromQName.clear();
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method sets the attributes, previous attributes are cleared,
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * it also keeps the hashtable up to date for quick lookup via
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * getIndex(qName).
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param atts the attributes to copy into these attributes.
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see org.xml.sax.helpers.AttributesImpl#setAttributes(Attributes)
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see #getIndex(String)
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final void setAttributes(Attributes atts)
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        super.setAttributes(atts);
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // we've let the super class add the attributes, but
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // we need to keep the hash table up to date ourselves for the
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // potentially new qName/index pairs for quick lookup.
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int numAtts = atts.getLength();
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (MAX <= numAtts)
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            switchOverToHash(numAtts);
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * This method gets the index of an attribute given its uri and locanName.
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param uri the URI of the attribute name.
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param localName the local namer (after the ':' ) of the attribute name.
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the integer index of the attribute.
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see org.xml.sax.Attributes#getIndex(String)
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final int getIndex(String uri, String localName)
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int index;
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (super.getLength() < MAX)
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // if we haven't got too many attributes let the
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // super class look it up
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            index = super.getIndex(uri,localName);
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return index;
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // we have too many attributes and the super class is slow
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // so find it quickly using our Hashtable.
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Form the key of format "{uri}localName"
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_buff.setLength(0);
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_buff.append('{').append(uri).append('}').append(localName);
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String key = m_buff.toString();
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Integer i = (Integer)m_indexFromQName.get(key);
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (i == null)
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            index = -1;
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            index = i.intValue();
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return index;
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
238