Move some code around, simplify
[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 getLeft() {
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 getRight() {
29         return right;
30     }
31
32     ModifierSet ms;
33     /**
34      * The set of modifiers that are applied to this boolean.
35      */
36     public List<Modifier> getModifiers() {
37         return ms.getModifiers();
38     }
39
40     protected CQLBooleanNode(CQLNode left, CQLNode right, ModifierSet ms) {
41         this.left = left;
42         this.right = right;
43         this.ms = ms;
44     }
45
46     @Override
47     void toXCQLInternal(XCQLBuilder b, int level,
48         List<CQLPrefix> prefixes, List<ModifierSet> sortkeys) {
49         b.indent(level).append("<triple>\n");
50         renderPrefixes(b, level + 1, prefixes);
51         ms.toXCQLInternal(b, level + 1, "boolean", "value");
52         b.indent(level + 1).append("<leftOperand>\n");
53         left.toXCQLInternal(b, level + 2);
54         b.indent(level + 1).append("</leftOperand>\n");
55         b.indent(level + 1).append("<rightOperand>\n");
56         right.toXCQLInternal(b, level + 2);
57         b.indent(level + 1).append("</rightOperand>\n");
58         renderSortKeys(b, level + 1, sortkeys);
59         b.indent(level).append("</triple>\n");
60     }
61
62     @Override
63     public String toCQL() {
64         // ### We don't always need parens around the operands
65         return ("(" + left.toCQL() + ")" +
66                 " " + ms.toCQL() + " " +
67                 "(" + right.toCQL() + ")");
68     }
69
70     @Override
71     public String toPQF(Properties config) throws PQFTranslationException {
72         return ("@" + opPQF() +
73                 " " + left.toPQF(config) +
74                 " " + right.toPQF(config));
75     }
76
77     // represents the operation for PQF: overridden for CQLProxNode
78     String opPQF() { return ms.getBase(); }
79
80     @Override
81     public byte[] toType1BER(Properties config) throws PQFTranslationException {
82         System.out.println("in CQLBooleanNode.toType1BER(): PQF=" +
83                            toPQF(config));
84         byte[] rpn1 = left.toType1BER(config);
85         byte[] rpn2 = right.toType1BER(config);
86         byte[] op = opType1();
87         byte[] rpnStructure = new byte[rpn1.length+rpn2.length+op.length+4];
88         
89         // rpnRpnOp
90         int offset = putTag(CONTEXT, 1, CONSTRUCTED, rpnStructure, 0);
91
92         rpnStructure[offset++] = (byte)(0x80&0xff); // indefinite length
93         System.arraycopy(rpn1, 0, rpnStructure, offset, rpn1.length);
94         offset += rpn1.length;
95         System.arraycopy(rpn2, 0, rpnStructure, offset, rpn2.length);
96         offset += rpn2.length;
97         System.arraycopy(op, 0, rpnStructure, offset, op.length);
98         offset += op.length;
99         rpnStructure[offset++] = 0x00; // end rpnRpnOp
100         rpnStructure[offset++] = 0x00;
101         return rpnStructure;
102     }
103
104     abstract byte[] opType1();
105 }