Add classes for visitor traversal
[cql-java-moved-to-github.git] / src / main / java / org / z3950 / zing / cql / CQLProxNode.java
1
2 package org.z3950.zing.cql;
3
4
5 /**
6  * Represents a proximity node in a CQL parse-tree.
7  * The left- and right-hand-sides must be satisfied by parts of the
8  * candidate records which are sufficiently close to each other, as
9  * specified by a set of proximity parameters.
10  *
11  */
12 public class CQLProxNode extends CQLBooleanNode {
13     /**
14      * Creates a new PROX node with the specified left- and right-hand
15      * sides and modifiers.
16      */
17     public CQLProxNode(CQLNode left, CQLNode right, ModifierSet ms) {
18         super(left, right, ms);
19     }
20
21     @Override
22     public void traverse(CQLNodeVisitor visitor) {
23       visitor.onProxNode(this);
24     }    
25
26     /*
27      * proximity ::= exclusion distance ordered relation which-code unit-code.
28      * exclusion ::= '1' | '0' | 'void'.
29      * distance ::= integer.
30      * ordered ::= '1' | '0'.
31      * relation ::= integer.
32      * which-code ::= 'known' | 'private' | integer.
33      * unit-code ::= integer.
34      */
35     @Override
36     String opPQF() {
37         int relCode = getRelCode();
38         int unitCode = getProxUnitCode();
39
40         String res = "prox " +
41             "0 " +
42             ms.modifier("distance") + " " +
43             (ms.modifier("ordering").equals("ordered") ? 1 : 0) + " " +
44             relCode + " " +
45             "1 " +
46             unitCode;
47
48         return res;
49     }
50
51     private int getRelCode() {
52         String rel = ms.modifier("relation");
53         if (rel.equals("<")) {
54             return 1;
55         } else if (rel.equals("<=")) {
56             return 2;
57         } else if (rel.equals("=")) {
58             return 3;
59         } else if (rel.equals(">=")) {
60             return 4;
61         } else if (rel.equals(">")) {
62             return 5;
63         } else if (rel.equals("<>")) {
64             return 6;
65         }
66         return 0;
67     }
68
69     private int getProxUnitCode() {
70         String unit = ms.modifier("unit");
71         if (unit.equals("word")) {
72             return 2;
73         } else if (unit.equals("sentence")) {
74             return 3;
75         } else if (unit.equals("paragraph")) {
76             return 4;
77         } else if (unit.equals("element")) {
78             return 8;
79         }
80         return 0;
81     }
82
83
84     @Override
85     byte[] opType1() {
86         byte[] op = new byte[100];
87         int offset, value;
88         offset = putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator
89         op[offset++] = (byte)(0x80&0xff); // indefinite length
90
91         offset = putTag(CONTEXT, 3, CONSTRUCTED, op, offset); // prox
92         op[offset++] = (byte)(0x80&0xff); // indefinite length
93
94         offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // exclusion
95         value = 0; // false
96         offset = putLen(numLen(value), op, offset);
97         offset = putNum(value, op, offset);
98
99         offset = putTag(CONTEXT, 2, PRIMITIVE, op, offset); // distance
100         value = Integer.parseInt(ms.modifier("distance"));
101         offset = putLen(numLen(value), op, offset);
102         offset = putNum(value, op, offset);
103
104         offset = putTag(CONTEXT, 3, PRIMITIVE, op, offset); // ordered
105         value = ms.modifier("ordering").equals("ordered") ? 1 : 0;
106         offset = putLen(numLen(value), op, offset);
107         offset = putNum(value, op, offset);
108
109         offset = putTag(CONTEXT, 4, PRIMITIVE, op, offset); // relationType
110         value = getRelCode();
111         offset = putLen(numLen(value), op, offset);
112         offset = putNum(value, op, offset);
113
114         offset = putTag(CONTEXT, 5, CONSTRUCTED, op, offset); // proximityUnitCode
115         op[offset++] = (byte)(0x80&0xff); // indefinite length
116         offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // known
117         value = getProxUnitCode();
118         offset = putLen(numLen(value), op, offset);
119         offset = putNum(value, op, offset);
120         op[offset++] = 0x00; // end of proximityUnitCode
121         op[offset++] = 0x00;
122
123         op[offset++] = 0x00; // end of prox
124         op[offset++] = 0x00;
125         op[offset++] = 0x00; // end of Operator
126         op[offset++] = 0x00;
127
128         byte[] o = new byte[offset];
129         System.arraycopy(op, 0, o, 0, offset);
130         return o;
131     }
132 }