XName.java 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright (c) 2003 Per M.A. Bothner.
  2. // This is free software; for terms and warranty disclaimer see ./COPYING.
  3. package gnu.xml;
  4. import gnu.mapping.*;
  5. import java.io.*;
  6. /** A QName with namespace nodes [and future optional type annotation]. */
  7. public class XName extends Symbol implements Externalizable
  8. {
  9. NamespaceBinding namespaceNodes;
  10. public XName ()
  11. {
  12. }
  13. public XName (Symbol symbol, NamespaceBinding namespaceNodes)
  14. {
  15. super(symbol.getName(), symbol.getNamespace());
  16. this.namespaceNodes = namespaceNodes;
  17. }
  18. /** Namespace nodes associated with an element.
  19. * These are in inverse document/parse order.
  20. */
  21. public final NamespaceBinding getNamespaceNodes () { return namespaceNodes; }
  22. public final void setNamespaceNodes (NamespaceBinding nodes)
  23. { this.namespaceNodes = nodes; }
  24. String lookupNamespaceURI (String prefix)
  25. {
  26. for (NamespaceBinding ns = namespaceNodes; ns != null; ns = ns.next)
  27. {
  28. if (prefix == ns.prefix)
  29. return ns.uri;
  30. }
  31. return null;
  32. }
  33. public void writeExternal(ObjectOutput out) throws IOException
  34. {
  35. super.writeExternal(out);
  36. out.writeObject(namespaceNodes);
  37. }
  38. public void readExternal(ObjectInput in)
  39. throws IOException, ClassNotFoundException
  40. {
  41. super.readExternal(in);
  42. namespaceNodes = (NamespaceBinding) in.readObject();
  43. }
  44. public static boolean isNameStart(int ch)
  45. {
  46. /* #ifdef JAVA5 */
  47. return Character.isUnicodeIdentifierStart(ch)
  48. /* #else */
  49. // return ch >= 0x10000 || Character.isUnicodeIdentifierStart((char) ch)
  50. /* #endif */
  51. || ch == '_';
  52. }
  53. public static boolean isNamePart(int ch)
  54. {
  55. /* #ifdef JAVA5 */
  56. return Character.isUnicodeIdentifierPart(ch)
  57. /* #else */
  58. // return ch >= 0x10000 || Character.isUnicodeIdentifierPart((char) ch)
  59. /* #endif */
  60. || ch == '-' || ch == '.';
  61. }
  62. public static boolean isNmToken (String value)
  63. {
  64. return checkName(value) >= 0;
  65. }
  66. public static boolean isName (String value)
  67. {
  68. return checkName(value) > 0;
  69. }
  70. public static boolean isNCName (String value)
  71. {
  72. return checkName(value) > 1;
  73. }
  74. /** Check if a string is a valid NMTOKEN, Name, or NCName.
  75. * @return 2 if string is an NCName; otherwise 1 if string is a Name;
  76. * otherwise 0 if string is an NMTOKEN; otherwise -1.
  77. */
  78. public static int checkName (String value)
  79. {
  80. int len = value.length();
  81. if (len == 0)
  82. return -1;
  83. int result = 2;
  84. for (int i = 0; i < len; )
  85. {
  86. boolean first = i == 0;
  87. int ch = value.charAt(i++);
  88. if (ch >= 0xD800 && ch < 0xDC00 && i < len)
  89. ch = (ch - 0xD800) * 0x400 + (value.charAt(i++) - 0xDC00) + 0x10000;
  90. if (ch == ':')
  91. {
  92. if (result == 2)
  93. result = 1;
  94. }
  95. else if (! XName.isNamePart(ch))
  96. return -1;
  97. else if (first && ! XName.isNameStart(ch))
  98. result = 0;
  99. }
  100. return result;
  101. }
  102. }