06a9bc9e1fe2aaa91a5aa88698ba72c3f99aac4f
[cql-java-moved-to-github.git] / src / main / java / org / z3950 / zing / cql / CQLBooleanNode.java
1 // $Id: CQLBooleanNode.java,v 1.18 2007-07-03 16:03:00 mike Exp $
2
3 package org.z3950.zing.cql;
4 import java.util.List;
5 import java.util.Properties;
6
7 /**
8  * Represents a boolean node in a CQL parse-tree.
9  *
10  * @version     $Id: CQLBooleanNode.java,v 1.18 2007-07-03 16:03:00 mike Exp $
11  */
12 public abstract class CQLBooleanNode extends CQLNode {
13
14     private CQLNode left;
15
16     /**
17      * The root of a parse-tree representing the left-hand side.
18      */
19     public CQLNode getLeftOperand() {
20         return left;
21     }
22
23     private CQLNode right;
24
25     /**
26      * The root of a parse-tree representing the right-hand side.
27      */
28     public CQLNode getRightOperand() {
29         return right;
30     }
31
32     ModifierSet ms;
33
34     /**
35      * The set of modifiers that are applied to this boolean.
36      */
37     public List<Modifier> getModifiers() {
38         return ms.getModifiers();
39     }
40
41     protected CQLBooleanNode(CQLNode left, CQLNode right, ModifierSet ms) {
42         this.left = left;
43         this.right = right;
44         this.ms = ms;
45     }
46
47     @Override
48     void toXCQLInternal(XCQLBuilder b, int level,
49         List<CQLPrefix> prefixes, List<ModifierSet> sortkeys) {
50         b.indent(level).append("<triple>\n");
51         renderPrefixes(b, level + 1, prefixes);
52         ms.toXCQLInternal(b, level + 1, "boolean", "value");
53         b.indent(level + 1).append("<leftOperand>\n");
54         left.toXCQLInternal(b, level + 2);
55         b.indent(level + 1).append("</leftOperand>\n");
56         b.indent(level + 1).append("<rightOperand>\n");
57         right.toXCQLInternal(b, level + 2);
58         b.indent(level + 1).append("</rightOperand>\n");
59         renderSortKeys(b, level + 1, sortkeys);
60         b.indent(level).append("</triple>\n");
61     }
62
63     @Override
64     public String toCQL() {
65         // ### We don't always need parens around the operands
66         return ("(" + left.toCQL() + ")" +
67                 " " + ms.toCQL() + " " +
68                 "(" + right.toCQL() + ")");
69     }
70
71     @Override
72     public String toPQF(Properties config) throws PQFTranslationException {
73         return ("@" + opPQF() +
74                 " " + left.toPQF(config) +
75                 " " + right.toPQF(config));
76     }
77
78     // represents the operation for PQF: overridden for CQLProxNode
79     String opPQF() { return ms.getBase(); }
80
81     @Override
82     public byte[] toType1BER(Properties config) throws PQFTranslationException {
83         System.out.println("in CQLBooleanNode.toType1BER(): PQF=" +
84                            toPQF(config));
85         byte[] rpn1 = left.toType1BER(config);
86         byte[] rpn2 = right.toType1BER(config);
87         byte[] op = opType1();
88         byte[] rpnStructure = new byte[rpn1.length+rpn2.length+op.length+4];
89         
90         // rpnRpnOp
91         int offset = putTag(CONTEXT, 1, CONSTRUCTED, rpnStructure, 0);
92
93         rpnStructure[offset++] = (byte)(0x80&0xff); // indefinite length
94         System.arraycopy(rpn1, 0, rpnStructure, offset, rpn1.length);
95         offset += rpn1.length;
96         System.arraycopy(rpn2, 0, rpnStructure, offset, rpn2.length);
97         offset += rpn2.length;
98         System.arraycopy(op, 0, rpnStructure, offset, op.length);
99         offset += op.length;
100         rpnStructure[offset++] = 0x00; // end rpnRpnOp
101         rpnStructure[offset++] = 0x00;
102         return rpnStructure;
103     }
104
105     abstract byte[] opType1();
106 }