1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xalan" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, Lotus
  53. * Development Corporation., http://www.lotus.com. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package org.apache.xml.dtm.ref;
  58. import org.apache.xml.dtm.DTM;
  59. import java.util.Vector;
  60. import java.util.Hashtable;
  61. /**
  62. * This is a default implementation of a table that manages mappings from
  63. * expanded names to expandedNameIDs.
  64. *
  65. * %REVIEW% Note that this is not really a separate table, or a
  66. * separate pool. Instead, it's an access method build on top of the
  67. * existing pools, using three pieces of information: the index
  68. * numbers for a node's namespaceURI, localName, and node type, which
  69. * are combined to yield a composite index number.
  70. *
  71. * %TBD% startup sequence -- how this gets access to the appropriate
  72. * string pools in the DTMDocument/stylesheet.
  73. *
  74. * */
  75. public class ExpandedNameTable
  76. {
  77. /** Probably a reference to static pool. */
  78. //private DTMStringPool m_locNamesPool;
  79. /** Probably a reference to static pool. */
  80. //private DTMStringPool m_namespaceNames;
  81. /** Vector of extended types for this document */
  82. private /*static*/ Vector m_extendedTypes;
  83. /** Next available extended type */
  84. private int m_nextType;
  85. // These are all the types prerotated, for caller convenience.
  86. public static final int ELEMENT = ((int)DTM.ELEMENT_NODE) ;
  87. public static final int ATTRIBUTE = ((int)DTM.ATTRIBUTE_NODE) ;
  88. public static final int TEXT = ((int)DTM.TEXT_NODE) ;
  89. public static final int CDATA_SECTION = ((int)DTM.CDATA_SECTION_NODE) ;
  90. public static final int ENTITY_REFERENCE = ((int)DTM.ENTITY_REFERENCE_NODE) ;
  91. public static final int ENTITY = ((int)DTM.ENTITY_NODE) ;
  92. public static final int PROCESSING_INSTRUCTION = ((int)DTM.PROCESSING_INSTRUCTION_NODE) ;
  93. public static final int COMMENT = ((int)DTM.COMMENT_NODE) ;
  94. public static final int DOCUMENT = ((int)DTM.DOCUMENT_NODE) ;
  95. public static final int DOCUMENT_TYPE = ((int)DTM.DOCUMENT_TYPE_NODE) ;
  96. public static final int DOCUMENT_FRAGMENT =((int)DTM.DOCUMENT_FRAGMENT_NODE) ;
  97. public static final int NOTATION = ((int)DTM.NOTATION_NODE) ;
  98. public static final int NAMESPACE = ((int)DTM.NAMESPACE_NODE) ;
  99. Hashtable m_hashtable = new Hashtable();
  100. /** Workspace for lookup. NOT THREAD SAFE!
  101. * */
  102. ExtendedType hashET=new ExtendedType(-1,"","");
  103. private static Hashtable m_defaultHashtable;
  104. private static Vector m_defaultExtendedTypes;
  105. /**
  106. * Init default vales
  107. */
  108. static {
  109. // use bigger values than default, to avoid reallocation in the future
  110. m_defaultExtendedTypes = new Vector(23);
  111. m_defaultHashtable = new Hashtable(23, 0.75f);
  112. for (int i = 0; i < DTM.NTYPES; i++)
  113. {
  114. ExtendedType newET = new ExtendedType(i, "", "");
  115. m_defaultExtendedTypes.addElement(newET);
  116. m_defaultHashtable.put(newET, new Integer(i));
  117. }
  118. }
  119. /**
  120. * Create an expanded name table that uses private string pool lookup.
  121. */
  122. public ExpandedNameTable()
  123. {
  124. //m_locNamesPool = new DTMSafeStringPool();
  125. //m_namespaceNames = new DTMSafeStringPool();
  126. initExtendedTypes();
  127. }
  128. /**
  129. * Constructor ExpandedNameTable
  130. *
  131. * @param locNamesPool Local element names lookup.
  132. * @param namespaceNames Namespace values lookup.
  133. */
  134. public ExpandedNameTable(DTMStringPool locNamesPool,
  135. DTMStringPool namespaceNames)
  136. {
  137. //m_locNamesPool = locNamesPool;
  138. //m_namespaceNames = namespaceNames;
  139. initExtendedTypes();
  140. }
  141. /**
  142. * Initialize the vector of extended types with the
  143. * basic DOM node types.
  144. */
  145. private void initExtendedTypes()
  146. {
  147. // Since objects in the Vector a m_extendedTypes and m_hashtable are never changed
  148. // it should be safe to copy default tables
  149. m_extendedTypes = (Vector)m_defaultExtendedTypes.clone();
  150. m_hashtable = (Hashtable)m_defaultHashtable.clone();
  151. m_nextType = m_extendedTypes.size();
  152. }
  153. /**
  154. * Given an expanded name, return an ID. If the expanded-name does not
  155. * exist in the internal tables, the entry will be created, and the ID will
  156. * be returned. Any additional nodes that are created that have this
  157. * expanded name will use this ID.
  158. *
  159. * @param namespace
  160. * @param localName
  161. *
  162. * @return the expanded-name id of the node.
  163. */
  164. public int getExpandedTypeID(String namespace, String localName, int type)
  165. {
  166. /*int nsID = (null != namespace) ? m_namespaceNames.stringToIndex(namespace) : 0;
  167. int lnID = m_locNamesPool.stringToIndex(localName);
  168. int expandedTypeID = (type << (BITS_PER_NAMESPACE+BITS_PER_LOCALNAME))
  169. | (nsID << BITS_PER_LOCALNAME) | lnID;
  170. return expandedTypeID;
  171. */
  172. if (null == namespace)
  173. namespace = "";
  174. if (null == localName)
  175. localName = "";
  176. // Set our reusable ExpandedType so we can look
  177. // it up in the hashtable. Not threadsafe, but
  178. // avoids creating a new object until we know
  179. // this isn't one we've seen before.
  180. hashET.redefine(type,namespace,localName);
  181. Object eType;
  182. if ((eType = m_hashtable.get(hashET)) != null )
  183. return ((Integer)eType).intValue();
  184. ExtendedType newET=new ExtendedType(type, namespace, localName);
  185. m_extendedTypes.addElement(newET);
  186. m_hashtable.put(newET, new Integer(m_nextType));
  187. return m_nextType++;
  188. }
  189. /**
  190. * Given a type, return an expanded name ID.Any additional nodes that are
  191. * created that have this expanded name will use this ID.
  192. *
  193. * @param namespace
  194. * @param localName
  195. *
  196. * @return the expanded-name id of the node.
  197. */
  198. public int getExpandedTypeID(int type)
  199. {
  200. return type;
  201. }
  202. /**
  203. * Given an expanded-name ID, return the local name part.
  204. *
  205. * @param ExpandedNameID an ID that represents an expanded-name.
  206. * @return String Local name of this node, or null if the node has no name.
  207. */
  208. public String getLocalName(int ExpandedNameID)
  209. {
  210. //return m_locNamesPool.indexToString(ExpandedNameID & MASK_LOCALNAME);
  211. ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt (ExpandedNameID);
  212. return etype.localName;
  213. }
  214. /**
  215. * Given an expanded-name ID, return the local name ID.
  216. *
  217. * @param ExpandedNameID an ID that represents an expanded-name.
  218. * @return The id of this local name.
  219. */
  220. public /*static*/ final int getLocalNameID(int ExpandedNameID)
  221. {
  222. //return (ExpandedNameID & MASK_LOCALNAME);
  223. ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt (ExpandedNameID);
  224. if (etype.localName.equals(""))
  225. return 0;
  226. else
  227. return ExpandedNameID;
  228. }
  229. /**
  230. * Given an expanded-name ID, return the namespace URI part.
  231. *
  232. * @param ExpandedNameID an ID that represents an expanded-name.
  233. * @return String URI value of this node's namespace, or null if no
  234. * namespace was resolved.
  235. */
  236. public String getNamespace(int ExpandedNameID)
  237. {
  238. //int id = (ExpandedNameID & MASK_NAMESPACE) >> BITS_PER_LOCALNAME;
  239. //return (0 == id) ? null : m_namespaceNames.indexToString(id);
  240. ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt (ExpandedNameID);
  241. return (etype.namespace.equals("") ? null : etype.namespace);
  242. }
  243. /**
  244. * Given an expanded-name ID, return the namespace URI ID.
  245. *
  246. * @param ExpandedNameID an ID that represents an expanded-name.
  247. * @return The id of this namespace.
  248. */
  249. public /*static*/ final int getNamespaceID(int ExpandedNameID)
  250. {
  251. //return (ExpandedNameID & MASK_NAMESPACE) >> BITS_PER_LOCALNAME;
  252. ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt (ExpandedNameID);
  253. if (etype.namespace.equals(""))
  254. return 0;
  255. else
  256. return ExpandedNameID;
  257. }
  258. /**
  259. * Given an expanded-name ID, return the local name ID.
  260. *
  261. * @param ExpandedNameID an ID that represents an expanded-name.
  262. * @return The id of this local name.
  263. */
  264. public final short getType(int ExpandedNameID)
  265. {
  266. //return (short)(ExpandedNameID >> ROTAMOUNT_TYPE);
  267. ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt (ExpandedNameID);
  268. return (short)etype.nodetype;
  269. }
  270. /**
  271. * Private class representing an extended type object
  272. */
  273. private static class ExtendedType
  274. {
  275. protected int nodetype;
  276. protected String namespace;
  277. protected String localName;
  278. protected int hash;
  279. protected ExtendedType (int nodetype, String namespace, String localName)
  280. {
  281. this.nodetype = nodetype;
  282. this.namespace = namespace;
  283. this.localName = localName;
  284. this.hash=nodetype+namespace.hashCode()+localName.hashCode();
  285. }
  286. /* This is intended to be used ONLY on the hashET
  287. * object. Using it elsewhere will mess up existing
  288. * hashtable entries!
  289. * */
  290. protected void redefine(int nodetype, String namespace, String localName)
  291. {
  292. this.nodetype = nodetype;
  293. this.namespace = namespace;
  294. this.localName = localName;
  295. this.hash=nodetype+namespace.hashCode()+localName.hashCode();
  296. }
  297. /* Override super method
  298. * */
  299. public int hashCode()
  300. {
  301. return hash;
  302. }
  303. /* Override super method
  304. * */
  305. public boolean equals(Object other)
  306. {
  307. //Usually an optimization, but
  308. // won't arise in our usage:
  309. //if(other==this) return true;
  310. try
  311. {
  312. ExtendedType et=(ExtendedType)other;
  313. return et.nodetype==this.nodetype &&
  314. et.localName.equals(this.localName) &&
  315. et.namespace.equals(this.namespace);
  316. }
  317. catch(ClassCastException e)
  318. {
  319. return false;
  320. }
  321. catch(NullPointerException e)
  322. {
  323. return false;
  324. }
  325. }
  326. }
  327. }