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