X-Git-Url: http://lists.indexdata.dk/cgi-bin?a=blobdiff_plain;ds=sidebyside;f=src%2Forg%2Fz3950%2Fzing%2Fcql%2FCQLProxNode.java;h=d0ac772b58904456e4717a6b7255ab7e09f4d376;hb=ad441f7588070233573d763992e71fe8dc867a4d;hp=1b9abe9ce3e1a04db0382e6a22ae04469dd4199a;hpb=f8154c71944186a9b64ddb782082a2026c5a912f;p=cql-java-moved-to-github.git diff --git a/src/org/z3950/zing/cql/CQLProxNode.java b/src/org/z3950/zing/cql/CQLProxNode.java index 1b9abe9..d0ac772 100644 --- a/src/org/z3950/zing/cql/CQLProxNode.java +++ b/src/org/z3950/zing/cql/CQLProxNode.java @@ -1,37 +1,179 @@ -// $Id: CQLProxNode.java,v 1.1 2002-10-31 22:22:01 mike Exp $ +// $Id: CQLProxNode.java,v 1.8 2007-06-27 17:02:01 mike Exp $ package org.z3950.zing.cql; +import java.util.Vector; /** * Represents a proximity node in a CQL parse-tree. - * ## + * The left- and right-hand-sides must be satisfied by parts of the + * candidate records which are sufficiently close to each other, as + * specified by a set of proximity parameters. * - * @version $Id: CQLProxNode.java,v 1.1 2002-10-31 22:22:01 mike Exp $ + * @version $Id: CQLProxNode.java,v 1.8 2007-06-27 17:02:01 mike Exp $ */ public class CQLProxNode extends CQLBooleanNode { ModifierSet ms; + /** + * Creates a new, incomplete, proximity node with the + * specified left-hand side. No right-hand side is specified at + * this stage: that must be specified later, using the + * addSecondSubterm() method. (That may seem odd, but + * it's just easier to write the parser that way.) + *

+ * Proximity paramaters may be added at any time, before or after + * the right-hand-side sub-tree is added. + */ public CQLProxNode(CQLNode left) { ms = new ModifierSet("prox"); this.left = left; // this.right left unresolved for now ... } - // ... delayed "second half" of the constructor + /** + * Sets the right-hand side of the proximity node whose + * left-hand-side was specified at creation time. + */ public void addSecondSubterm(CQLNode right) { this.right = right; } + /** + * Adds a modifier of the specified type and + * value to a proximity node. Valid types are + * relation, distance, unit and + * ordering. + *

+ * For information on the semantics of these paramaters, see + * section 3.1 (Proximity) of + * A Gentle Introduction to CQL. + */ + public void addModifier(String type, String value) { + ms.addModifier(type, value); + } + + /** + * Returns an array of the modifiers associated with a proximity + * node. + * @return + * An array of Modifier objects. + */ + public Vector getModifiers() { + return ms.getModifiers(); + } + String op() { return ms.toCQL(); } - public void addModifier(String type, String value) { - ms.addModifier(type, value); + String opXCQL(int level) { + return ms.toXCQL(level, "boolean"); } - String booleanXQL(int level) { - return ms.toXCQL(level, "boolean"); + /* + * proximity ::= exclusion distance ordered relation which-code unit-code. + * exclusion ::= '1' | '0' | 'void'. + * distance ::= integer. + * ordered ::= '1' | '0'. + * relation ::= integer. + * which-code ::= 'known' | 'private' | integer. + * unit-code ::= integer. + */ + String opPQF() { + int relCode = getRelCode(); + int unitCode = getProxUnitCode(); + + String res = "prox " + + "0 " + + ms.modifier("distance") + " " + + (ms.modifier("ordering").equals("ordered") ? 1 : 0) + " " + + relCode + " " + + "1 " + + unitCode; + + return res; + } + + private int getRelCode() { + String rel = ms.modifier("relation"); + if (rel.equals("<")) { + return 1; + } else if (rel.equals("<=")) { + return 2; + } else if (rel.equals("=")) { + return 3; + } else if (rel.equals(">=")) { + return 4; + } else if (rel.equals(">")) { + return 5; + } else if (rel.equals("<>")) { + return 6; + } + return 0; + } + + private int getProxUnitCode() { + String unit = ms.modifier("unit"); + if (unit.equals("word")) { + return 2; + } else if (unit.equals("sentence")) { + return 3; + } else if (unit.equals("paragraph")) { + return 4; + } else if (unit.equals("element")) { + return 8; + } + return 0; + } + + + byte[] opType1() { + byte[] op = new byte[100]; + int offset, value; + offset = putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator + op[offset++] = (byte)(0x80&0xff); // indefinite length + + offset = putTag(CONTEXT, 3, CONSTRUCTED, op, offset); // prox + op[offset++] = (byte)(0x80&0xff); // indefinite length + + offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // exclusion + value = 0; // false + offset = putLen(numLen(value), op, offset); + offset = putNum(value, op, offset); + + offset = putTag(CONTEXT, 2, PRIMITIVE, op, offset); // distance + value = Integer.parseInt(ms.modifier("distance")); + offset = putLen(numLen(value), op, offset); + offset = putNum(value, op, offset); + + offset = putTag(CONTEXT, 3, PRIMITIVE, op, offset); // ordered + value = ms.modifier("ordering").equals("ordered") ? 1 : 0; + offset = putLen(numLen(value), op, offset); + offset = putNum(value, op, offset); + + offset = putTag(CONTEXT, 4, PRIMITIVE, op, offset); // relationType + value = getRelCode(); + offset = putLen(numLen(value), op, offset); + offset = putNum(value, op, offset); + + offset = putTag(CONTEXT, 5, CONSTRUCTED, op, offset); // proximityUnitCode + op[offset++] = (byte)(0x80&0xff); // indefinite length + offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // known + value = getProxUnitCode(); + offset = putLen(numLen(value), op, offset); + offset = putNum(value, op, offset); + op[offset++] = 0x00; // end of proximityUnitCode + op[offset++] = 0x00; + + op[offset++] = 0x00; // end of prox + op[offset++] = 0x00; + op[offset++] = 0x00; // end of Operator + op[offset++] = 0x00; + + byte[] o = new byte[offset]; + System.arraycopy(op, 0, o, 0, offset); + return o; } }