Remove relation keywords TT_ANY, TT_ALL, and TT_EXACT.
[cql-java-moved-to-github.git] / src / org / z3950 / zing / cql / CQLProxNode.java
1 // $Id: CQLProxNode.java,v 1.9 2007-06-27 22:15:04 mike Exp $
2
3 package org.z3950.zing.cql;
4 import java.util.Vector;
5
6
7 /**
8  * Represents a proximity node in a CQL parse-tree.
9  * The left- and right-hand-sides must be satisfied by parts of the
10  * candidate records which are sufficiently close to each other, as
11  * specified by a set of proximity parameters.
12  *
13  * @version     $Id: CQLProxNode.java,v 1.9 2007-06-27 22:15:04 mike Exp $
14  */
15 public class CQLProxNode extends CQLBooleanNode {
16     ModifierSet ms;
17
18     /**
19      * Creates a new, <I>incomplete</I>, proximity node with the
20      * specified left-hand side.  No right-hand side is specified at
21      * this stage: that must be specified later, using the
22      * <TT>addSecondSubterm()</TT> method.  (That may seem odd, but
23      * it's just easier to write the parser that way.)
24      * <P>
25      * Proximity paramaters may be added at any time, before or after
26      * the right-hand-side sub-tree is added.
27      */
28     public CQLProxNode(CQLNode left) {
29         ms = new ModifierSet("prox");
30         this.left = left;
31         // this.right left unresolved for now ...
32     }
33
34     /**
35      * Sets the right-hand side of the proximity node whose
36      * left-hand-side was specified at creation time.
37      */
38     public void addSecondSubterm(CQLNode right) {
39         this.right = right;
40     }
41
42     /**
43      * Adds a modifier of the specified <TT>type</TT>,
44      * <TT>comparison</TT> and <TT>value</TT> to a proximity node.
45      */
46     public void addModifier(String type, String comparison, String value) {
47         ms.addModifier(type, comparison, value);
48     }
49
50     /**
51      * Returns an array of the modifiers associated with a proximity
52      * node.
53      * @return
54      *  An array of Modifier objects.
55      */
56     public Vector<Modifier> getModifiers() {
57         return ms.getModifiers();
58     }
59
60     String op() {
61         return ms.toCQL();
62     }
63
64     String opXCQL(int level) {
65         return ms.toXCQL(level, "boolean");
66     }
67
68     /*
69      * proximity ::= exclusion distance ordered relation which-code unit-code.
70      * exclusion ::= '1' | '0' | 'void'.
71      * distance ::= integer.
72      * ordered ::= '1' | '0'.
73      * relation ::= integer.
74      * which-code ::= 'known' | 'private' | integer.
75      * unit-code ::= integer.
76      */
77     String opPQF() {
78         int relCode = getRelCode();
79         int unitCode = getProxUnitCode();
80
81         String res = "prox " +
82             "0 " +
83             ms.modifier("distance") + " " +
84             (ms.modifier("ordering").equals("ordered") ? 1 : 0) + " " +
85             relCode + " " +
86             "1 " +
87             unitCode;
88
89         return res;
90     }
91
92     private int getRelCode() {
93         String rel = ms.modifier("relation");
94         if (rel.equals("<")) {
95             return 1;
96         } else if (rel.equals("<=")) {
97             return 2;
98         } else if (rel.equals("=")) {
99             return 3;
100         } else if (rel.equals(">=")) {
101             return 4;
102         } else if (rel.equals(">")) {
103             return 5;
104         } else if (rel.equals("<>")) {
105             return 6;
106         }
107         return 0;
108     }
109
110     private int getProxUnitCode() {
111         String unit = ms.modifier("unit");
112         if (unit.equals("word")) {
113             return 2;
114         } else if (unit.equals("sentence")) {
115             return 3;
116         } else if (unit.equals("paragraph")) {
117             return 4;
118         } else if (unit.equals("element")) {
119             return 8;
120         }
121         return 0;
122     }
123
124
125     byte[] opType1() {
126         byte[] op = new byte[100];
127         int offset, value;
128         offset = putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator
129         op[offset++] = (byte)(0x80&0xff); // indefinite length
130
131         offset = putTag(CONTEXT, 3, CONSTRUCTED, op, offset); // prox
132         op[offset++] = (byte)(0x80&0xff); // indefinite length
133
134         offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // exclusion
135         value = 0; // false
136         offset = putLen(numLen(value), op, offset);
137         offset = putNum(value, op, offset);
138
139         offset = putTag(CONTEXT, 2, PRIMITIVE, op, offset); // distance
140         value = Integer.parseInt(ms.modifier("distance"));
141         offset = putLen(numLen(value), op, offset);
142         offset = putNum(value, op, offset);
143
144         offset = putTag(CONTEXT, 3, PRIMITIVE, op, offset); // ordered
145         value = ms.modifier("ordering").equals("ordered") ? 1 : 0;
146         offset = putLen(numLen(value), op, offset);
147         offset = putNum(value, op, offset);
148
149         offset = putTag(CONTEXT, 4, PRIMITIVE, op, offset); // relationType
150         value = getRelCode();
151         offset = putLen(numLen(value), op, offset);
152         offset = putNum(value, op, offset);
153
154         offset = putTag(CONTEXT, 5, CONSTRUCTED, op, offset); // proximityUnitCode
155         op[offset++] = (byte)(0x80&0xff); // indefinite length
156         offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // known
157         value = getProxUnitCode();
158         offset = putLen(numLen(value), op, offset);
159         offset = putNum(value, op, offset);
160         op[offset++] = 0x00; // end of proximityUnitCode
161         op[offset++] = 0x00;
162
163         op[offset++] = 0x00; // end of prox
164         op[offset++] = 0x00;
165         op[offset++] = 0x00; // end of Operator
166         op[offset++] = 0x00;
167
168         byte[] o = new byte[offset];
169         System.arraycopy(op, 0, o, 0, offset);
170         return o;
171     }
172 }