b4c6fa85e0a49d531d8646e5d4a0d6d43d75f974
[cql-java-moved-to-github.git] / src / org / z3950 / zing / ralph / CQLProxNode.java
1 // $Id: CQLProxNode.java,v 1.1 2002-12-04 16:54:01 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.1 2002-12-04 16:54:01 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> and
44      * <TT>value</TT> to a proximity node.  Valid types are
45      * <TT>relation</TT>, <TT>distance</TT>, <TT>unit</TT> and
46      * <TT>ordering</TT>.
47      * <P>
48      * For information on the semantics of these paramaters, see
49      * <A href="http://zing.z3950.org/cql/intro.html#3.1"
50      *  >section 3.1 (Proximity)</A> of
51      * <I>A Gentle Introduction to CQL</I></A>.
52      */
53     public void addModifier(String type, String value) {
54         ms.addModifier(type, value);
55     }
56
57     /**
58      * Returns an array of the modifiers associated with a proximity
59      * node.
60      * @return
61      *  An array of modifiers, each represented by a two-element
62      *  <TT>Vector</TT>, in which element 0 is the modifier type
63      *  (e.g. <TT>distance</TT> or <TT>ordering</TT>) and element 1 is
64      *  the associated value (e.g. <TT>3</TT> or <TT>unordered</TT>).
65      */
66     public Vector[] getModifiers() {
67         return ms.getModifiers();
68     }
69
70     String op() {
71         return ms.toCQL();
72     }
73
74     String opXCQL(int level) {
75         return ms.toXCQL(level, "boolean");
76     }
77
78     /*
79      * proximity ::= exclusion distance ordered relation which-code unit-code.
80      * exclusion ::= '1' | '0' | 'void'.
81      * distance ::= integer.
82      * ordered ::= '1' | '0'.
83      * relation ::= integer.
84      * which-code ::= 'known' | 'private' | integer.
85      * unit-code ::= integer.
86      */
87     String opPQF() {
88         int relCode = getRelCode();
89
90         int unitCode = getProxUnitCode();
91
92         String res = "prox " +
93             "0 " +
94             ms.modifier("distance") + " " +
95             (ms.modifier("ordering").equals("ordered") ? 1 : 0) + " " +
96             relCode + " " +
97             "1 " +
98             unitCode;
99         
100         return res;
101     }
102
103     private int getRelCode() {
104         String rel = ms.modifier("relation");
105         if (rel.equals("<")) {
106             return 1;
107         } else if (rel.equals("<=")) {
108             return 2;
109         } else if (rel.equals("=")) {
110             return 3;
111         } else if (rel.equals(">=")) {
112             return 4;
113         } else if (rel.equals(">")) {
114             return 5;
115         } else if (rel.equals("<>")) {
116             return 6;
117         }
118         return 0;
119     }
120     
121     private int getProxUnitCode() {
122         String unit = ms.modifier("unit");
123         if (unit.equals("word")) {
124             return 2;
125         } else if (unit.equals("sentence")) {
126             return 3;
127         } else if (unit.equals("paragraph")) {
128             return 4;
129         } else if (unit.equals("element")) {
130             return 8;
131         }
132         return 0;
133     }
134     
135     
136     byte[] opType1() {
137         byte[] op=new byte[100];
138         int    offset, value;
139         offset=putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator
140         op[offset++]=(byte)(0x80&0xff); // indefinite length
141
142         offset=putTag(CONTEXT, 3, CONSTRUCTED, op, offset); // prox
143         op[offset++]=(byte)(0x80&0xff); // indefinite length
144
145         offset=putTag(CONTEXT, 1, PRIMITIVE, op, offset); // exclusion
146         value=0; // value=0=false
147         offset=putLen(numLen(value), op, offset);
148         offset=putNum(value, op, offset);
149
150         offset=putTag(CONTEXT, 2, PRIMITIVE, op, offset); // distance
151         value=Integer.parseInt(ms.modifier("distance"));
152         offset=putLen(numLen(value), op, offset);
153         offset=putNum(value, op, offset);
154         
155         offset=putTag(CONTEXT, 3, PRIMITIVE, op, offset); // ordered
156         value=ms.modifier("ordering").equals("ordered") ? 1 : 0;
157         offset=putLen(numLen(value), op, offset);
158         offset=putNum(value, op, offset);
159         
160         offset=putTag(CONTEXT, 4, PRIMITIVE, op, offset); // relationType
161         value=getRelCode();
162         offset=putLen(numLen(value), op, offset);
163         offset=putNum(value, op, offset);
164         
165         offset=putTag(CONTEXT, 5, CONSTRUCTED, op, offset); // proximityUnitCode
166         op[offset++]=(byte)(0x80&0xff); // indefinite length
167         offset=putTag(CONTEXT, 1, PRIMITIVE, op, offset); // known
168         value=getProxUnitCode();
169         offset=putLen(numLen(value), op, offset);
170         offset=putNum(value, op, offset);
171         op[offset++]=0x00; // end of proximityUnitCode
172         op[offset++]=0x00;
173         
174         op[offset++]=0x00; // end of prox
175         op[offset++]=0x00;
176         op[offset++]=0x00; // end of Operator
177         op[offset++]=0x00;
178         
179         byte[] o=new byte[offset];
180         System.arraycopy(op, 0, o, 0, offset);
181         return o;
182     }
183     
184 }