| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 1999 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "Xalan" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache", |
| * nor may "Apache" appear in their name, without prior written |
| * permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation and was |
| * originally based on software copyright (c) 1999, Lotus |
| * Development Corporation., http://www.lotus.com. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| */ |
| package org.apache.xml.dtm.ref; |
| |
| import org.apache.xml.dtm.DTM; |
| |
| import java.util.Vector; |
| import java.util.Hashtable; |
| |
| /** |
| * This is a default implementation of a table that manages mappings from |
| * expanded names to expandedNameIDs. |
| * |
| * %REVIEW% Note that this is not really a separate table, or a |
| * separate pool. Instead, it's an access method build on top of the |
| * existing pools, using three pieces of information: the index |
| * numbers for a node's namespaceURI, localName, and node type, which |
| * are combined to yield a composite index number. |
| * |
| * %TBD% startup sequence -- how this gets access to the appropriate |
| * string pools in the DTMDocument/stylesheet. |
| * |
| * */ |
| public class ExpandedNameTable |
| { |
| |
| /** Probably a reference to static pool. */ |
| //private DTMStringPool m_locNamesPool; |
| |
| /** Probably a reference to static pool. */ |
| //private DTMStringPool m_namespaceNames; |
| |
| /** Vector of extended types for this document */ |
| private /*static*/ Vector m_extendedTypes; |
| |
| /** Next available extended type */ |
| private int m_nextType; |
| |
| // These are all the types prerotated, for caller convenience. |
| public static final int ELEMENT = ((int)DTM.ELEMENT_NODE) ; |
| public static final int ATTRIBUTE = ((int)DTM.ATTRIBUTE_NODE) ; |
| public static final int TEXT = ((int)DTM.TEXT_NODE) ; |
| public static final int CDATA_SECTION = ((int)DTM.CDATA_SECTION_NODE) ; |
| public static final int ENTITY_REFERENCE = ((int)DTM.ENTITY_REFERENCE_NODE) ; |
| public static final int ENTITY = ((int)DTM.ENTITY_NODE) ; |
| public static final int PROCESSING_INSTRUCTION = ((int)DTM.PROCESSING_INSTRUCTION_NODE) ; |
| public static final int COMMENT = ((int)DTM.COMMENT_NODE) ; |
| public static final int DOCUMENT = ((int)DTM.DOCUMENT_NODE) ; |
| public static final int DOCUMENT_TYPE = ((int)DTM.DOCUMENT_TYPE_NODE) ; |
| public static final int DOCUMENT_FRAGMENT =((int)DTM.DOCUMENT_FRAGMENT_NODE) ; |
| public static final int NOTATION = ((int)DTM.NOTATION_NODE) ; |
| public static final int NAMESPACE = ((int)DTM.NAMESPACE_NODE) ; |
| |
| Hashtable m_hashtable = new Hashtable(); |
| |
| /** Workspace for lookup. NOT THREAD SAFE! |
| * */ |
| ExtendedType hashET=new ExtendedType(-1,"",""); |
| |
| private static Hashtable m_defaultHashtable; |
| private static Vector m_defaultExtendedTypes; |
| |
| /** |
| * Init default vales |
| */ |
| static { |
| // use bigger values than default, to avoid reallocation in the future |
| m_defaultExtendedTypes = new Vector(23); |
| m_defaultHashtable = new Hashtable(23, 0.75f); |
| |
| for (int i = 0; i < DTM.NTYPES; i++) |
| { |
| ExtendedType newET = new ExtendedType(i, "", ""); |
| m_defaultExtendedTypes.addElement(newET); |
| m_defaultHashtable.put(newET, new Integer(i)); |
| } |
| } |
| |
| /** |
| * Create an expanded name table that uses private string pool lookup. |
| */ |
| public ExpandedNameTable() |
| { |
| //m_locNamesPool = new DTMSafeStringPool(); |
| //m_namespaceNames = new DTMSafeStringPool(); |
| initExtendedTypes(); |
| } |
| |
| /** |
| * Constructor ExpandedNameTable |
| * |
| * @param locNamesPool Local element names lookup. |
| * @param namespaceNames Namespace values lookup. |
| */ |
| public ExpandedNameTable(DTMStringPool locNamesPool, |
| DTMStringPool namespaceNames) |
| { |
| //m_locNamesPool = locNamesPool; |
| //m_namespaceNames = namespaceNames; |
| initExtendedTypes(); |
| } |
| |
| /** |
| * Initialize the vector of extended types with the |
| * basic DOM node types. |
| */ |
| private void initExtendedTypes() |
| { |
| // Since objects in the Vector a m_extendedTypes and m_hashtable are never changed |
| // it should be safe to copy default tables |
| m_extendedTypes = (Vector)m_defaultExtendedTypes.clone(); |
| m_hashtable = (Hashtable)m_defaultHashtable.clone(); |
| m_nextType = m_extendedTypes.size(); |
| } |
| |
| /** |
| * Given an expanded name, return an ID. If the expanded-name does not |
| * exist in the internal tables, the entry will be created, and the ID will |
| * be returned. Any additional nodes that are created that have this |
| * expanded name will use this ID. |
| * |
| * @param namespace |
| * @param localName |
| * |
| * @return the expanded-name id of the node. |
| */ |
| public int getExpandedTypeID(String namespace, String localName, int type) |
| { |
| /*int nsID = (null != namespace) ? m_namespaceNames.stringToIndex(namespace) : 0; |
| int lnID = m_locNamesPool.stringToIndex(localName); |
| |
| int expandedTypeID = (type << (BITS_PER_NAMESPACE+BITS_PER_LOCALNAME)) |
| | (nsID << BITS_PER_LOCALNAME) | lnID; |
| return expandedTypeID; |
| */ |
| if (null == namespace) |
| namespace = ""; |
| if (null == localName) |
| localName = ""; |
| // Set our reusable ExpandedType so we can look |
| // it up in the hashtable. Not threadsafe, but |
| // avoids creating a new object until we know |
| // this isn't one we've seen before. |
| hashET.redefine(type,namespace,localName); |
| |
| Object eType; |
| if ((eType = m_hashtable.get(hashET)) != null ) |
| return ((Integer)eType).intValue(); |
| |
| ExtendedType newET=new ExtendedType(type, namespace, localName); |
| m_extendedTypes.addElement(newET); |
| m_hashtable.put(newET, new Integer(m_nextType)); |
| return m_nextType++; |
| } |
| |
| /** |
| * Given a type, return an expanded name ID.Any additional nodes that are |
| * created that have this expanded name will use this ID. |
| * |
| * @param namespace |
| * @param localName |
| * |
| * @return the expanded-name id of the node. |
| */ |
| public int getExpandedTypeID(int type) |
| { |
| return type; |
| } |
| |
| /** |
| * Given an expanded-name ID, return the local name part. |
| * |
| * @param ExpandedNameID an ID that represents an expanded-name. |
| * @return String Local name of this node, or null if the node has no name. |
| */ |
| public String getLocalName(int ExpandedNameID) |
| { |
| //return m_locNamesPool.indexToString(ExpandedNameID & MASK_LOCALNAME); |
| ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt (ExpandedNameID); |
| return etype.localName; |
| } |
| |
| /** |
| * Given an expanded-name ID, return the local name ID. |
| * |
| * @param ExpandedNameID an ID that represents an expanded-name. |
| * @return The id of this local name. |
| */ |
| public /*static*/ final int getLocalNameID(int ExpandedNameID) |
| { |
| //return (ExpandedNameID & MASK_LOCALNAME); |
| ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt (ExpandedNameID); |
| if (etype.localName.equals("")) |
| return 0; |
| else |
| return ExpandedNameID; |
| } |
| |
| |
| /** |
| * Given an expanded-name ID, return the namespace URI part. |
| * |
| * @param ExpandedNameID an ID that represents an expanded-name. |
| * @return String URI value of this node's namespace, or null if no |
| * namespace was resolved. |
| */ |
| public String getNamespace(int ExpandedNameID) |
| { |
| |
| //int id = (ExpandedNameID & MASK_NAMESPACE) >> BITS_PER_LOCALNAME; |
| //return (0 == id) ? null : m_namespaceNames.indexToString(id); |
| ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt (ExpandedNameID); |
| return (etype.namespace.equals("") ? null : etype.namespace); |
| } |
| |
| /** |
| * Given an expanded-name ID, return the namespace URI ID. |
| * |
| * @param ExpandedNameID an ID that represents an expanded-name. |
| * @return The id of this namespace. |
| */ |
| public /*static*/ final int getNamespaceID(int ExpandedNameID) |
| { |
| //return (ExpandedNameID & MASK_NAMESPACE) >> BITS_PER_LOCALNAME; |
| ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt (ExpandedNameID); |
| if (etype.namespace.equals("")) |
| return 0; |
| else |
| return ExpandedNameID; |
| } |
| |
| /** |
| * Given an expanded-name ID, return the local name ID. |
| * |
| * @param ExpandedNameID an ID that represents an expanded-name. |
| * @return The id of this local name. |
| */ |
| public final short getType(int ExpandedNameID) |
| { |
| //return (short)(ExpandedNameID >> ROTAMOUNT_TYPE); |
| ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt (ExpandedNameID); |
| return (short)etype.nodetype; |
| } |
| |
| |
| /** |
| * Private class representing an extended type object |
| */ |
| private static class ExtendedType |
| { |
| protected int nodetype; |
| protected String namespace; |
| protected String localName; |
| protected int hash; |
| |
| protected ExtendedType (int nodetype, String namespace, String localName) |
| { |
| this.nodetype = nodetype; |
| this.namespace = namespace; |
| this.localName = localName; |
| this.hash=nodetype+namespace.hashCode()+localName.hashCode(); |
| } |
| |
| /* This is intended to be used ONLY on the hashET |
| * object. Using it elsewhere will mess up existing |
| * hashtable entries! |
| * */ |
| protected void redefine(int nodetype, String namespace, String localName) |
| { |
| this.nodetype = nodetype; |
| this.namespace = namespace; |
| this.localName = localName; |
| this.hash=nodetype+namespace.hashCode()+localName.hashCode(); |
| } |
| |
| /* Override super method |
| * */ |
| public int hashCode() |
| { |
| return hash; |
| } |
| |
| /* Override super method |
| * */ |
| public boolean equals(Object other) |
| { |
| //Usually an optimization, but |
| // won't arise in our usage: |
| //if(other==this) return true; |
| try |
| { |
| ExtendedType et=(ExtendedType)other; |
| return et.nodetype==this.nodetype && |
| et.localName.equals(this.localName) && |
| et.namespace.equals(this.namespace); |
| } |
| catch(ClassCastException e) |
| { |
| return false; |
| } |
| catch(NullPointerException e) |
| { |
| return false; |
| } |
| } |
| } |
| |
| } |