NodeCompare.java 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package gnu.kawa.xml;
  2. import gnu.mapping.*;
  3. import gnu.lists.*;
  4. /** Compare nodes for document order.
  5. * Implements the XQuery operators '{@code <<}', '{@code >>}', '{@code is}', '{@code isnot}'.
  6. */
  7. public class NodeCompare extends Procedure2
  8. {
  9. // Return codes from Numeric.compare:
  10. static final int RESULT_GRT = 1;
  11. static final int RESULT_EQU = 0;
  12. static final int RESULT_LSS = -1;
  13. // One flag bit for each of the above RESULT_XXX codes:
  14. static final int TRUE_IF_GRT = 1 << (RESULT_GRT + 3);
  15. static final int TRUE_IF_EQU = 1 << (RESULT_EQU + 3);
  16. static final int TRUE_IF_LSS = 1 << (RESULT_LSS + 3);
  17. int flags;
  18. // The funny name of the static fields and methods correspond to
  19. // the name mangling scheme defined in Compilation.mangleName.
  20. // They can therefor be statically resolved by the compiler.
  21. public static final NodeCompare $Eq = make("is",TRUE_IF_EQU);
  22. public static final NodeCompare $Ne = make("isnot",TRUE_IF_LSS|TRUE_IF_GRT);
  23. public static final NodeCompare $Gr = make(">>",TRUE_IF_GRT);
  24. public static final NodeCompare $Ls = make("<<",TRUE_IF_LSS);
  25. public static NodeCompare make(String name, int flags)
  26. {
  27. NodeCompare proc = new NodeCompare();
  28. proc.setName(name);
  29. proc.flags = flags;
  30. return proc;
  31. }
  32. public Object apply2 (Object arg1, Object arg2)
  33. {
  34. if (arg1 == null || arg2 == null)
  35. return null;
  36. if (arg1 == Values.empty)
  37. return arg1;
  38. if (arg2 == Values.empty)
  39. return arg2;
  40. AbstractSequence seq1, seq2;
  41. int ipos1, ipos2;
  42. if (arg1 instanceof AbstractSequence)
  43. {
  44. seq1 = (AbstractSequence) arg1;
  45. ipos1 = seq1.startPos();
  46. }
  47. else
  48. {
  49. try
  50. {
  51. SeqPosition spos = (SeqPosition) arg1;
  52. seq1 = spos.sequence;
  53. ipos1 = spos.getPos();
  54. }
  55. catch (ClassCastException ex)
  56. {
  57. throw WrongType.make(ex, this, 1, arg1);
  58. }
  59. }
  60. if (arg2 instanceof AbstractSequence)
  61. {
  62. seq2 = (AbstractSequence) arg2;
  63. ipos2 = seq2.startPos();
  64. }
  65. else
  66. {
  67. try
  68. {
  69. SeqPosition spos = (SeqPosition) arg2;
  70. seq2 = spos.sequence;
  71. ipos2 = spos.getPos();
  72. }
  73. catch (ClassCastException ex)
  74. {
  75. throw WrongType.make(ex, this, 2, arg2);
  76. }
  77. }
  78. int comp;
  79. if (seq1 == seq2)
  80. comp = seq1.compare(ipos1, ipos2);
  81. else if (this == $Eq)
  82. return Boolean.FALSE;
  83. else if (this == $Ne)
  84. return Boolean.TRUE;
  85. else
  86. comp = seq1.stableCompare(seq2);
  87. if ((1 << (3 + comp) & flags) != 0)
  88. return Boolean.TRUE;
  89. else
  90. return Boolean.FALSE;
  91. }
  92. }