1 2 3 package org.objectstyle.cayenne.exp.parser; 4 5 import java.io.PrintWriter ; 6 7 import org.objectstyle.cayenne.exp.Expression; 8 import org.objectstyle.cayenne.exp.ExpressionException; 9 import org.objectstyle.cayenne.util.Util; 10 11 20 public abstract class SimpleNode extends Expression implements Node { 21 protected Node parent; 22 protected Node[] children; 23 protected int id; 24 25 28 protected static void encodeScalarAsString(PrintWriter pw, Object scalar) { 29 boolean quote = scalar instanceof String ; 30 31 if (quote) { 32 pw.print('\"'); 33 } 34 encodeAsEscapedString(pw, String.valueOf(scalar)); 35 if (quote) { 36 pw.print('\"'); 37 } 38 } 39 40 44 protected static void encodeAsEscapedString(PrintWriter pw, String source) { 45 int len = source.length(); 46 for (int i = 0; i < len; i++) { 47 char c = source.charAt(i); 48 49 switch (c) { 50 case '\n' : 51 pw.print("\\n"); 52 continue; 53 case '\r' : 54 pw.print("\\r"); 55 continue; 56 case '\t' : 57 pw.print("\\t"); 58 continue; 59 case '\b' : 60 pw.print("\\b"); 61 continue; 62 case '\f' : 63 pw.print("\\f"); 64 continue; 65 case '\\' : 66 pw.print("\\\\"); 67 continue; 68 case '\'' : 69 pw.print("\\'"); 70 continue; 71 case '\"' : 72 pw.print("\\\""); 73 continue; 74 default : 75 pw.print(c); 76 } 77 } 78 } 79 80 protected SimpleNode(int i) { 81 id = i; 82 } 83 84 protected abstract String getExpressionOperator(int index); 85 86 protected boolean pruneNodeForPrunedChild(Object prunedChild) { 87 return true; 88 } 89 90 93 public String expName() { 94 return ExpressionParserTreeConstants.jjtNodeName[id]; 95 } 96 97 101 protected void flattenTree() { 102 boolean shouldFlatten = false; 103 int newSize = 0; 104 105 for (int i = 0; i < children.length; i++) { 106 if (children[i].getClass() == getClass()) { 107 shouldFlatten = true; 108 newSize += children[i].jjtGetNumChildren(); 109 } 110 else { 111 newSize++; 112 } 113 } 114 115 if (shouldFlatten) { 116 Node[] newChildren = new Node[newSize]; 117 int j = 0; 118 119 for (int i = 0; i < children.length; ++i) { 120 Node c = children[i]; 121 if (c.getClass() == getClass()) { 122 for (int k = 0; k < c.jjtGetNumChildren(); ++k) 123 newChildren[j++] = c.jjtGetChild(k); 124 } 125 else { 126 newChildren[j++] = c; 127 } 128 } 129 130 if (j != newSize) { 131 throw new ExpressionException("Assertion error: " + j + " != " + newSize); 132 } 133 134 this.children = newChildren; 135 } 136 } 137 138 public void encodeAsString(PrintWriter pw) { 139 if (parent != null) { 140 pw.print("("); 141 } 142 143 if ((children != null) && (children.length > 0)) { 144 for (int i = 0; i < children.length; ++i) { 145 if (i > 0) { 146 pw.print(' '); 147 pw.print(getExpressionOperator(i)); 148 pw.print(' '); 149 } 150 151 ((SimpleNode) children[i]).encodeAsString(pw); 152 } 153 } 154 155 if (parent != null) { 156 pw.print(')'); 157 } 158 } 159 160 public Object getOperand(int index) { 161 Node child = jjtGetChild(index); 162 163 return unwrapChild(child); 167 } 168 169 protected Node wrapChild(Object child) { 170 return (child instanceof Node || child == null) 171 ? (Node) child 172 : new ASTScalar(child); 173 } 174 175 protected Object unwrapChild(Node child) { 176 return (child instanceof ASTScalar) ? ((ASTScalar) child).getValue() : child; 177 } 178 179 public int getOperandCount() { 180 return jjtGetNumChildren(); 181 } 182 183 public void setOperand(int index, Object value) { 184 Node node = (value == null || value instanceof Node) 185 ? (Node) value 186 : new ASTScalar(value); 187 jjtAddChild(node, index); 188 189 if (node != null) { 191 node.jjtSetParent(this); 192 } 193 } 194 195 public void jjtOpen() { 196 197 } 198 199 public void jjtClose() { 200 201 } 202 203 public void jjtSetParent(Node n) { 204 parent = n; 205 } 206 207 public Node jjtGetParent() { 208 return parent; 209 } 210 211 public void jjtAddChild(Node n, int i) { 212 if (children == null) { 213 children = new Node[i + 1]; 214 } 215 else if (i >= children.length) { 216 Node c[] = new Node[i + 1]; 217 System.arraycopy(children, 0, c, 0, children.length); 218 children = c; 219 } 220 children[i] = n; 221 } 222 223 public Node jjtGetChild(int i) { 224 return children[i]; 225 } 226 227 public final int jjtGetNumChildren() { 228 return (children == null) ? 0 : children.length; 229 } 230 231 234 protected abstract Object evaluateNode(Object o) throws Exception ; 235 236 protected Object evaluateChild(int index, Object o) throws Exception { 237 return ((SimpleNode) jjtGetChild(index)).evaluate(o); 238 } 239 240 public Object evaluate(Object o) { 241 try { 243 return evaluateNode(o); 244 } 245 catch (Throwable th) { 246 String string = this.toString(); 247 throw new ExpressionException( 248 "Error evaluating expression '" + string + "'", 249 string, 250 Util.unwindException(th)); 251 } 252 } 253 } 254 | Popular Tags |