1 // $Id: CQLProxNode.java,v 1.7 2002-12-05 17:14:52 mike Exp $
3 package org.z3950.zing.cql;
4 import java.util.Vector;
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.
13 * @version $Id: CQLProxNode.java,v 1.7 2002-12-05 17:14:52 mike Exp $
15 public class CQLProxNode extends CQLBooleanNode {
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.)
25 * Proximity paramaters may be added at any time, before or after
26 * the right-hand-side sub-tree is added.
28 public CQLProxNode(CQLNode left) {
29 ms = new ModifierSet("prox");
31 // this.right left unresolved for now ...
35 * Sets the right-hand side of the proximity node whose
36 * left-hand-side was specified at creation time.
38 public void addSecondSubterm(CQLNode right) {
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
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>.
53 public void addModifier(String type, String value) {
54 ms.addModifier(type, value);
58 * Returns an array of the modifiers associated with a proximity
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>).
66 public Vector[] getModifiers() {
67 return ms.getModifiers();
74 String opXCQL(int level) {
75 return ms.toXCQL(level, "boolean");
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.
88 int relCode = getRelCode();
89 int unitCode = getProxUnitCode();
91 String res = "prox " +
93 ms.modifier("distance") + " " +
94 (ms.modifier("ordering").equals("ordered") ? 1 : 0) + " " +
102 private int getRelCode() {
103 String rel = ms.modifier("relation");
104 if (rel.equals("<")) {
106 } else if (rel.equals("<=")) {
108 } else if (rel.equals("=")) {
110 } else if (rel.equals(">=")) {
112 } else if (rel.equals(">")) {
114 } else if (rel.equals("<>")) {
120 private int getProxUnitCode() {
121 String unit = ms.modifier("unit");
122 if (unit.equals("word")) {
124 } else if (unit.equals("sentence")) {
126 } else if (unit.equals("paragraph")) {
128 } else if (unit.equals("element")) {
136 byte[] op = new byte[100];
138 offset = putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator
139 op[offset++] = (byte)(0x80&0xff); // indefinite length
141 offset = putTag(CONTEXT, 3, CONSTRUCTED, op, offset); // prox
142 op[offset++] = (byte)(0x80&0xff); // indefinite length
144 offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // exclusion
146 offset = putLen(numLen(value), op, offset);
147 offset = putNum(value, op, offset);
149 offset = putTag(CONTEXT, 2, PRIMITIVE, op, offset); // distance
150 value = Integer.parseInt(ms.modifier("distance"));
151 offset = putLen(numLen(value), op, offset);
152 offset = putNum(value, op, offset);
154 offset = putTag(CONTEXT, 3, PRIMITIVE, op, offset); // ordered
155 value = ms.modifier("ordering").equals("ordered") ? 1 : 0;
156 offset = putLen(numLen(value), op, offset);
157 offset = putNum(value, op, offset);
159 offset = putTag(CONTEXT, 4, PRIMITIVE, op, offset); // relationType
160 value = getRelCode();
161 offset = putLen(numLen(value), op, offset);
162 offset = putNum(value, op, offset);
164 offset = putTag(CONTEXT, 5, CONSTRUCTED, op, offset); // proximityUnitCode
165 op[offset++] = (byte)(0x80&0xff); // indefinite length
166 offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // known
167 value = getProxUnitCode();
168 offset = putLen(numLen(value), op, offset);
169 offset = putNum(value, op, offset);
170 op[offset++] = 0x00; // end of proximityUnitCode
173 op[offset++] = 0x00; // end of prox
175 op[offset++] = 0x00; // end of Operator
178 byte[] o = new byte[offset];
179 System.arraycopy(op, 0, o, 0, offset);