PageRenderTime 648ms CodeModel.GetById 27ms RepoModel.GetById 15ms app.codeStats 2ms

/projects/jre-1.6.0/src/com/sun/org/apache/xml/internal/utils/QName.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 707 lines | 343 code | 94 blank | 270 comment | 78 complexity | 117db5973abf1bbad4667054b2a5404e MD5 | raw file
  1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. * $Id: QName.java,v 1.2.4.1 2005/09/15 08:15:52 suresh_emailid Exp $
  18. */
  19. package com.sun.org.apache.xml.internal.utils;
  20. import java.util.Stack;
  21. import java.util.StringTokenizer;
  22. import com.sun.org.apache.xml.internal.res.XMLErrorResources;
  23. import com.sun.org.apache.xml.internal.res.XMLMessages;
  24. import org.w3c.dom.Element;
  25. /**
  26. * Class to represent a qualified name: "The name of an internal XSLT object,
  27. * specifically a named template (see [7 Named Templates]), a mode (see [6.7 Modes]),
  28. * an attribute set (see [8.1.4 Named Attribute Sets]), a key (see [14.2 Keys]),
  29. * a locale (see [14.3 Number Formatting]), a variable or a parameter (see
  30. * [12 Variables and Parameters]) is specified as a QName. If it has a prefix,
  31. * then the prefix is expanded into a URI reference using the namespace declarations
  32. * in effect on the attribute in which the name occurs. The expanded name
  33. * consisting of the local part of the name and the possibly null URI reference
  34. * is used as the name of the object. The default namespace is not used for
  35. * unprefixed names."
  36. * @xsl.usage general
  37. */
  38. public class QName implements java.io.Serializable
  39. {
  40. static final long serialVersionUID = 467434581652829920L;
  41. /**
  42. * The local name.
  43. * @serial
  44. */
  45. protected String _localName;
  46. /**
  47. * The namespace URI.
  48. * @serial
  49. */
  50. protected String _namespaceURI;
  51. /**
  52. * The namespace prefix.
  53. * @serial
  54. */
  55. protected String _prefix;
  56. /**
  57. * The XML namespace.
  58. */
  59. public static final String S_XMLNAMESPACEURI =
  60. "http://www.w3.org/XML/1998/namespace";
  61. /**
  62. * The cached hashcode, which is calculated at construction time.
  63. * @serial
  64. */
  65. private int m_hashCode;
  66. /**
  67. * Constructs an empty QName.
  68. * 20001019: Try making this public, to support Serializable? -- JKESS
  69. */
  70. public QName(){}
  71. /**
  72. * Constructs a new QName with the specified namespace URI and
  73. * local name.
  74. *
  75. * @param namespaceURI The namespace URI if known, or null
  76. * @param localName The local name
  77. */
  78. public QName(String namespaceURI, String localName)
  79. {
  80. this(namespaceURI, localName, false);
  81. }
  82. /**
  83. * Constructs a new QName with the specified namespace URI and
  84. * local name.
  85. *
  86. * @param namespaceURI The namespace URI if known, or null
  87. * @param localName The local name
  88. * @param validate If true the new QName will be validated and an IllegalArgumentException will
  89. * be thrown if it is invalid.
  90. */
  91. public QName(String namespaceURI, String localName, boolean validate)
  92. {
  93. // This check was already here. So, for now, I will not add it to the validation
  94. // that is done when the validate parameter is true.
  95. if (localName == null)
  96. throw new IllegalArgumentException(XMLMessages.createXMLMessage(
  97. XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");
  98. if (validate)
  99. {
  100. if (!XML11Char.isXML11ValidNCName(localName))
  101. {
  102. throw new IllegalArgumentException(XMLMessages.createXMLMessage(
  103. XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
  104. }
  105. }
  106. _namespaceURI = namespaceURI;
  107. _localName = localName;
  108. m_hashCode = toString().hashCode();
  109. }
  110. /**
  111. * Constructs a new QName with the specified namespace URI, prefix
  112. * and local name.
  113. *
  114. * @param namespaceURI The namespace URI if known, or null
  115. * @param prefix The namespace prefix is known, or null
  116. * @param localName The local name
  117. *
  118. */
  119. public QName(String namespaceURI, String prefix, String localName)
  120. {
  121. this(namespaceURI, prefix, localName, false);
  122. }
  123. /**
  124. * Constructs a new QName with the specified namespace URI, prefix
  125. * and local name.
  126. *
  127. * @param namespaceURI The namespace URI if known, or null
  128. * @param prefix The namespace prefix is known, or null
  129. * @param localName The local name
  130. * @param validate If true the new QName will be validated and an IllegalArgumentException will
  131. * be thrown if it is invalid.
  132. */
  133. public QName(String namespaceURI, String prefix, String localName, boolean validate)
  134. {
  135. // This check was already here. So, for now, I will not add it to the validation
  136. // that is done when the validate parameter is true.
  137. if (localName == null)
  138. throw new IllegalArgumentException(XMLMessages.createXMLMessage(
  139. XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");
  140. if (validate)
  141. {
  142. if (!XML11Char.isXML11ValidNCName(localName))
  143. {
  144. throw new IllegalArgumentException(XMLMessages.createXMLMessage(
  145. XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
  146. }
  147. if ((null != prefix) && (!XML11Char.isXML11ValidNCName(prefix)))
  148. {
  149. throw new IllegalArgumentException(XMLMessages.createXMLMessage(
  150. XMLErrorResources.ER_ARG_PREFIX_INVALID,null )); //"Argument 'prefix' not a valid NCName");
  151. }
  152. }
  153. _namespaceURI = namespaceURI;
  154. _prefix = prefix;
  155. _localName = localName;
  156. m_hashCode = toString().hashCode();
  157. }
  158. /**
  159. * Construct a QName from a string, without namespace resolution. Good
  160. * for a few odd cases.
  161. *
  162. * @param localName Local part of qualified name
  163. *
  164. */
  165. public QName(String localName)
  166. {
  167. this(localName, false);
  168. }
  169. /**
  170. * Construct a QName from a string, without namespace resolution. Good
  171. * for a few odd cases.
  172. *
  173. * @param localName Local part of qualified name
  174. * @param validate If true the new QName will be validated and an IllegalArgumentException will
  175. * be thrown if it is invalid.
  176. */
  177. public QName(String localName, boolean validate)
  178. {
  179. // This check was already here. So, for now, I will not add it to the validation
  180. // that is done when the validate parameter is true.
  181. if (localName == null)
  182. throw new IllegalArgumentException(XMLMessages.createXMLMessage(
  183. XMLErrorResources.ER_ARG_LOCALNAME_NULL, null)); //"Argument 'localName' is null");
  184. if (validate)
  185. {
  186. if (!XML11Char.isXML11ValidNCName(localName))
  187. {
  188. throw new IllegalArgumentException(XMLMessages.createXMLMessage(
  189. XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
  190. }
  191. }
  192. _namespaceURI = null;
  193. _localName = localName;
  194. m_hashCode = toString().hashCode();
  195. }
  196. /**
  197. * Construct a QName from a string, resolving the prefix
  198. * using the given namespace stack. The default namespace is
  199. * not resolved.
  200. *
  201. * @param qname Qualified name to resolve
  202. * @param namespaces Namespace stack to use to resolve namespace
  203. */
  204. public QName(String qname, Stack namespaces)
  205. {
  206. this(qname, namespaces, false);
  207. }
  208. /**
  209. * Construct a QName from a string, resolving the prefix
  210. * using the given namespace stack. The default namespace is
  211. * not resolved.
  212. *
  213. * @param qname Qualified name to resolve
  214. * @param namespaces Namespace stack to use to resolve namespace
  215. * @param validate If true the new QName will be validated and an IllegalArgumentException will
  216. * be thrown if it is invalid.
  217. */
  218. public QName(String qname, Stack namespaces, boolean validate)
  219. {
  220. String namespace = null;
  221. String prefix = null;
  222. int indexOfNSSep = qname.indexOf(':');
  223. if (indexOfNSSep > 0)
  224. {
  225. prefix = qname.substring(0, indexOfNSSep);
  226. if (prefix.equals("xml"))
  227. {
  228. namespace = S_XMLNAMESPACEURI;
  229. }
  230. // Do we want this?
  231. else if (prefix.equals("xmlns"))
  232. {
  233. return;
  234. }
  235. else
  236. {
  237. int depth = namespaces.size();
  238. for (int i = depth - 1; i >= 0; i--)
  239. {
  240. NameSpace ns = (NameSpace) namespaces.elementAt(i);
  241. while (null != ns)
  242. {
  243. if ((null != ns.m_prefix) && prefix.equals(ns.m_prefix))
  244. {
  245. namespace = ns.m_uri;
  246. i = -1;
  247. break;
  248. }
  249. ns = ns.m_next;
  250. }
  251. }
  252. }
  253. if (null == namespace)
  254. {
  255. throw new RuntimeException(
  256. XMLMessages.createXMLMessage(
  257. XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
  258. new Object[]{ prefix })); //"Prefix must resolve to a namespace: "+prefix);
  259. }
  260. }
  261. _localName = (indexOfNSSep < 0)
  262. ? qname : qname.substring(indexOfNSSep + 1);
  263. if (validate)
  264. {
  265. if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName)))
  266. {
  267. throw new IllegalArgumentException(XMLMessages.createXMLMessage(
  268. XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
  269. }
  270. }
  271. _namespaceURI = namespace;
  272. _prefix = prefix;
  273. m_hashCode = toString().hashCode();
  274. }
  275. /**
  276. * Construct a QName from a string, resolving the prefix
  277. * using the given namespace context and prefix resolver.
  278. * The default namespace is not resolved.
  279. *
  280. * @param qname Qualified name to resolve
  281. * @param namespaceContext Namespace Context to use
  282. * @param resolver Prefix resolver for this context
  283. */
  284. public QName(String qname, Element namespaceContext,
  285. PrefixResolver resolver)
  286. {
  287. this(qname, namespaceContext, resolver, false);
  288. }
  289. /**
  290. * Construct a QName from a string, resolving the prefix
  291. * using the given namespace context and prefix resolver.
  292. * The default namespace is not resolved.
  293. *
  294. * @param qname Qualified name to resolve
  295. * @param namespaceContext Namespace Context to use
  296. * @param resolver Prefix resolver for this context
  297. * @param validate If true the new QName will be validated and an IllegalArgumentException will
  298. * be thrown if it is invalid.
  299. */
  300. public QName(String qname, Element namespaceContext,
  301. PrefixResolver resolver, boolean validate)
  302. {
  303. _namespaceURI = null;
  304. int indexOfNSSep = qname.indexOf(':');
  305. if (indexOfNSSep > 0)
  306. {
  307. if (null != namespaceContext)
  308. {
  309. String prefix = qname.substring(0, indexOfNSSep);
  310. _prefix = prefix;
  311. if (prefix.equals("xml"))
  312. {
  313. _namespaceURI = S_XMLNAMESPACEURI;
  314. }
  315. // Do we want this?
  316. else if (prefix.equals("xmlns"))
  317. {
  318. return;
  319. }
  320. else
  321. {
  322. _namespaceURI = resolver.getNamespaceForPrefix(prefix,
  323. namespaceContext);
  324. }
  325. if (null == _namespaceURI)
  326. {
  327. throw new RuntimeException(
  328. XMLMessages.createXMLMessage(
  329. XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
  330. new Object[]{ prefix })); //"Prefix must resolve to a namespace: "+prefix);
  331. }
  332. }
  333. else
  334. {
  335. // TODO: error or warning...
  336. }
  337. }
  338. _localName = (indexOfNSSep < 0)
  339. ? qname : qname.substring(indexOfNSSep + 1);
  340. if (validate)
  341. {
  342. if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName)))
  343. {
  344. throw new IllegalArgumentException(XMLMessages.createXMLMessage(
  345. XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
  346. }
  347. }
  348. m_hashCode = toString().hashCode();
  349. }
  350. /**
  351. * Construct a QName from a string, resolving the prefix
  352. * using the given namespace stack. The default namespace is
  353. * not resolved.
  354. *
  355. * @param qname Qualified name to resolve
  356. * @param resolver Prefix resolver for this context
  357. */
  358. public QName(String qname, PrefixResolver resolver)
  359. {
  360. this(qname, resolver, false);
  361. }
  362. /**
  363. * Construct a QName from a string, resolving the prefix
  364. * using the given namespace stack. The default namespace is
  365. * not resolved.
  366. *
  367. * @param qname Qualified name to resolve
  368. * @param resolver Prefix resolver for this context
  369. * @param validate If true the new QName will be validated and an IllegalArgumentException will
  370. * be thrown if it is invalid.
  371. */
  372. public QName(String qname, PrefixResolver resolver, boolean validate)
  373. {
  374. String prefix = null;
  375. _namespaceURI = null;
  376. int indexOfNSSep = qname.indexOf(':');
  377. if (indexOfNSSep > 0)
  378. {
  379. prefix = qname.substring(0, indexOfNSSep);
  380. if (prefix.equals("xml"))
  381. {
  382. _namespaceURI = S_XMLNAMESPACEURI;
  383. }
  384. else
  385. {
  386. _namespaceURI = resolver.getNamespaceForPrefix(prefix);
  387. }
  388. if (null == _namespaceURI)
  389. {
  390. throw new RuntimeException(
  391. XMLMessages.createXMLMessage(
  392. XMLErrorResources.ER_PREFIX_MUST_RESOLVE,
  393. new Object[]{ prefix })); //"Prefix must resolve to a namespace: "+prefix);
  394. }
  395. _localName = qname.substring(indexOfNSSep + 1);
  396. }
  397. else if (indexOfNSSep == 0)
  398. {
  399. throw new RuntimeException(
  400. XMLMessages.createXMLMessage(
  401. XMLErrorResources.ER_NAME_CANT_START_WITH_COLON,
  402. null));
  403. }
  404. else
  405. {
  406. _localName = qname;
  407. }
  408. if (validate)
  409. {
  410. if ((_localName == null) || (!XML11Char.isXML11ValidNCName(_localName)))
  411. {
  412. throw new IllegalArgumentException(XMLMessages.createXMLMessage(
  413. XMLErrorResources.ER_ARG_LOCALNAME_INVALID,null )); //"Argument 'localName' not a valid NCName");
  414. }
  415. }
  416. m_hashCode = toString().hashCode();
  417. _prefix = prefix;
  418. }
  419. /**
  420. * Returns the namespace URI. Returns null if the namespace URI
  421. * is not known.
  422. *
  423. * @return The namespace URI, or null
  424. */
  425. public String getNamespaceURI()
  426. {
  427. return _namespaceURI;
  428. }
  429. /**
  430. * Returns the namespace prefix. Returns null if the namespace
  431. * prefix is not known.
  432. *
  433. * @return The namespace prefix, or null
  434. */
  435. public String getPrefix()
  436. {
  437. return _prefix;
  438. }
  439. /**
  440. * Returns the local part of the qualified name.
  441. *
  442. * @return The local part of the qualified name
  443. */
  444. public String getLocalName()
  445. {
  446. return _localName;
  447. }
  448. /**
  449. * Return the string representation of the qualified name, using the
  450. * prefix if available, or the '{ns}foo' notation if not. Performs
  451. * string concatenation, so beware of performance issues.
  452. *
  453. * @return the string representation of the namespace
  454. */
  455. public String toString()
  456. {
  457. return _prefix != null
  458. ? (_prefix + ":" + _localName)
  459. : (_namespaceURI != null
  460. ? ("{"+_namespaceURI + "}" + _localName) : _localName);
  461. }
  462. /**
  463. * Return the string representation of the qualified name using the
  464. * the '{ns}foo' notation. Performs
  465. * string concatenation, so beware of performance issues.
  466. *
  467. * @return the string representation of the namespace
  468. */
  469. public String toNamespacedString()
  470. {
  471. return (_namespaceURI != null
  472. ? ("{"+_namespaceURI + "}" + _localName) : _localName);
  473. }
  474. /**
  475. * Get the namespace of the qualified name.
  476. *
  477. * @return the namespace URI of the qualified name
  478. */
  479. public String getNamespace()
  480. {
  481. return getNamespaceURI();
  482. }
  483. /**
  484. * Get the local part of the qualified name.
  485. *
  486. * @return the local part of the qualified name
  487. */
  488. public String getLocalPart()
  489. {
  490. return getLocalName();
  491. }
  492. /**
  493. * Return the cached hashcode of the qualified name.
  494. *
  495. * @return the cached hashcode of the qualified name
  496. */
  497. public int hashCode()
  498. {
  499. return m_hashCode;
  500. }
  501. /**
  502. * Override equals and agree that we're equal if
  503. * the passed object is a string and it matches
  504. * the name of the arg.
  505. *
  506. * @param ns Namespace URI to compare to
  507. * @param localPart Local part of qualified name to compare to
  508. *
  509. * @return True if the local name and uri match
  510. */
  511. public boolean equals(String ns, String localPart)
  512. {
  513. String thisnamespace = getNamespaceURI();
  514. return getLocalName().equals(localPart)
  515. && (((null != thisnamespace) && (null != ns))
  516. ? thisnamespace.equals(ns)
  517. : ((null == thisnamespace) && (null == ns)));
  518. }
  519. /**
  520. * Override equals and agree that we're equal if
  521. * the passed object is a QName and it matches
  522. * the name of the arg.
  523. *
  524. * @return True if the qualified names are equal
  525. */
  526. public boolean equals(Object object)
  527. {
  528. if (object == this)
  529. return true;
  530. if (object instanceof QName) {
  531. QName qname = (QName) object;
  532. String thisnamespace = getNamespaceURI();
  533. String thatnamespace = qname.getNamespaceURI();
  534. return getLocalName().equals(qname.getLocalName())
  535. && (((null != thisnamespace) && (null != thatnamespace))
  536. ? thisnamespace.equals(thatnamespace)
  537. : ((null == thisnamespace) && (null == thatnamespace)));
  538. }
  539. else
  540. return false;
  541. }
  542. /**
  543. * Given a string, create and return a QName object
  544. *
  545. *
  546. * @param name String to use to create QName
  547. *
  548. * @return a QName object
  549. */
  550. public static QName getQNameFromString(String name)
  551. {
  552. StringTokenizer tokenizer = new StringTokenizer(name, "{}", false);
  553. QName qname;
  554. String s1 = tokenizer.nextToken();
  555. String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
  556. if (null == s2)
  557. qname = new QName(null, s1);
  558. else
  559. qname = new QName(s1, s2);
  560. return qname;
  561. }
  562. /**
  563. * This function tells if a raw attribute name is a
  564. * xmlns attribute.
  565. *
  566. * @param attRawName Raw name of attribute
  567. *
  568. * @return True if the attribute starts with or is equal to xmlns
  569. */
  570. public static boolean isXMLNSDecl(String attRawName)
  571. {
  572. return (attRawName.startsWith("xmlns")
  573. && (attRawName.equals("xmlns")
  574. || attRawName.startsWith("xmlns:")));
  575. }
  576. /**
  577. * This function tells if a raw attribute name is a
  578. * xmlns attribute.
  579. *
  580. * @param attRawName Raw name of attribute
  581. *
  582. * @return Prefix of attribute
  583. */
  584. public static String getPrefixFromXMLNSDecl(String attRawName)
  585. {
  586. int index = attRawName.indexOf(':');
  587. return (index >= 0) ? attRawName.substring(index + 1) : "";
  588. }
  589. /**
  590. * Returns the local name of the given node.
  591. *
  592. * @param qname Input name
  593. *
  594. * @return Local part of the name if prefixed, or the given name if not
  595. */
  596. public static String getLocalPart(String qname)
  597. {
  598. int index = qname.indexOf(':');
  599. return (index < 0) ? qname : qname.substring(index + 1);
  600. }
  601. /**
  602. * Returns the local name of the given node.
  603. *
  604. * @param qname Input name
  605. *
  606. * @return Prefix of name or empty string if none there
  607. */
  608. public static String getPrefixPart(String qname)
  609. {
  610. int index = qname.indexOf(':');
  611. return (index >= 0) ? qname.substring(0, index) : "";
  612. }
  613. }