1 18 package org.objectweb.speedo.generation.jorm.rdb; 19 20 import org.objectweb.speedo.query.parser.SpeedoQLVisitor; 21 import org.objectweb.speedo.query.parser.SimpleNode; 22 import org.objectweb.speedo.query.parser.ASTSpeedoPrimary; 23 import org.objectweb.speedo.query.parser.ASTSpeedoQL; 24 import org.objectweb.speedo.query.parser.ASTPrimary; 25 import org.objectweb.speedo.query.parser.ASTRelationalExpression; 26 import org.objectweb.speedo.query.parser.ASTAdditiveExpression; 27 import org.objectweb.speedo.query.parser.ASTUnaryExpression; 28 import org.objectweb.speedo.query.parser.ASTCastExpression; 29 import org.objectweb.speedo.query.parser.ASTArgumentList; 30 import org.objectweb.speedo.query.parser.ASTLiteral; 31 import org.objectweb.speedo.query.parser.ASTType; 32 import org.objectweb.speedo.query.parser.ASTQualifiedName; 33 import org.objectweb.speedo.query.parser.SpeedoQLConstants; 34 import org.objectweb.speedo.query.parser.SpeedoQL; 35 import org.objectweb.speedo.query.parser.ParseException; 36 import org.objectweb.speedo.api.SpeedoException; 37 import org.objectweb.speedo.metadata.SpeedoClass; 38 import org.objectweb.medor.expression.api.Expression; 39 import org.objectweb.medor.expression.api.Operator; 40 import org.objectweb.medor.expression.api.Operand; 41 import org.objectweb.medor.expression.lib.ConditionalOr; 42 import org.objectweb.medor.expression.lib.ConditionalAnd; 43 import org.objectweb.medor.expression.lib.Or; 44 import org.objectweb.medor.expression.lib.And; 45 import org.objectweb.medor.expression.lib.Equal; 46 import org.objectweb.medor.expression.lib.NotEqual; 47 import org.objectweb.medor.expression.lib.Lower; 48 import org.objectweb.medor.expression.lib.Greater; 49 import org.objectweb.medor.expression.lib.GreaterEqual; 50 import org.objectweb.medor.expression.lib.LowerEqual; 51 import org.objectweb.medor.expression.lib.Plus; 52 import org.objectweb.medor.expression.lib.Minus; 53 import org.objectweb.medor.expression.lib.Mult; 54 import org.objectweb.medor.expression.lib.DivideBy; 55 import org.objectweb.medor.expression.lib.UMinus; 56 import org.objectweb.medor.expression.lib.Bitwize; 57 import org.objectweb.medor.expression.lib.Not; 58 import org.objectweb.medor.expression.lib.BasicOperand; 59 import org.objectweb.util.monolog.api.BasicLevel; 60 import org.objectweb.util.monolog.api.Logger; 61 import org.objectweb.jorm.mapper.rdb.metainfo.RdbFilter; 62 import org.objectweb.jorm.type.api.PTypeSpace; 63 64 import java.util.Stack ; 65 import java.io.CharArrayReader ; 66 67 72 public class FilterManager { 73 74 private Logger logger; 75 private boolean debug = false; 76 private FilterParser parser = new FilterParser(); 77 78 public FilterManager(Logger logger) { 79 this.logger = logger; 80 } 81 82 public FilterParser getParser() { 83 return parser; 84 } 85 86 public void assignFilter(String filter, 87 RdbFilter rdbFilter, 88 SpeedoClass sc, 89 String projectName, 90 String mapperName) throws SpeedoException { 91 debug = logger != null && logger.isLoggable(BasicLevel.DEBUG); 92 Expression medorExpression = parser.parse(filter); 93 if (!isJormPredicate(medorExpression)) { 94 throw new SpeedoException( 95 "The specified filter is not supported, \n\tclass" 96 + sc.getFQName() + "\n\tfilter=" + filter); 97 } 98 rdbFilter.setExpression(medorExpression); 99 } 100 101 public class FilterParser implements SpeedoQLVisitor { 102 private Expression expression; 103 private String tab = ""; 104 105 public synchronized Expression parse(String filter) throws SpeedoException { 106 try { 107 visit(new SpeedoQL(new CharArrayReader (filter.toCharArray())).SpeedoQL()); 108 return expression; 109 } catch (ParseException e) { 110 throw new SpeedoException( 111 "Impossible to parse the filter and to create AST", e); 112 } catch (SpeedoException e) { 113 throw e; 114 } catch (Exception e) { 115 throw new SpeedoException("Impossible to parse the filter", e); 116 } 117 } 118 119 122 public Object visit(ASTPrimary node, Object data) { 123 visit((SimpleNode) node, data); 124 return null; 125 } 126 127 public Object visit(ASTSpeedoPrimary node, Object data) { 128 visit((SimpleNode) node, data); 129 Stack stack = (Stack ) data; 130 expression = (Expression) stack.pop(); 131 return null; 132 } 133 134 public Object visit(ASTRelationalExpression node, Object data) { 135 logger.log(BasicLevel.DEBUG, tab + "Visit RelationalExpression: " + node); 136 tab += '\t'; 137 visit((SimpleNode) node, data); 138 tab = tab.substring(1); 139 Stack stack = (Stack ) data; 140 if (stack.size() > 0) { 141 if (debug) { 142 logger.log(BasicLevel.DEBUG, "manage relational expression: " 143 + "(children: " + node.jjtGetNumChildren() 144 + ", stack: " + stack.size() 145 + ", peek:" + stack.peek() + ")"); 146 } 147 for (int i = 0; (i < (node.jjtGetNumChildren() - 1) && stack.size() > 0); i++) { 148 int op = ((Integer ) node.ops.get(node.jjtGetNumChildren() - 2 - i)).intValue(); 149 if (usedInRelationalExpresssion(op)) { 150 Object child2 = stack.pop(); 151 Object child1 = stack.pop(); 152 if (debug) { 153 logger.log(BasicLevel.DEBUG, "pop child1: " + child1); 154 logger.log(BasicLevel.DEBUG, "pop child2: " + child2); 155 } 156 Expression ret = null; 157 switch (op) { 158 case SpeedoQLConstants.OR: 159 ret = new ConditionalOr((Expression) child1, (Expression) child2); 160 break; 161 case SpeedoQLConstants.AND: 162 ret = new ConditionalAnd((Expression) child1, (Expression) child2); 163 break; 164 case SpeedoQLConstants.BITWISEOR: 165 ret = new Or((Expression) child1, (Expression) child2); 166 break; 167 case SpeedoQLConstants.BITWISEXOR: 168 ret = null; 169 break; 170 case SpeedoQLConstants.BITWISEAND: 171 ret = new And((Expression) child1, (Expression) child2); 172 break; 173 case SpeedoQLConstants.EQ: 174 ret = new Equal((Expression) child1, (Expression) child2); 175 break; 176 case SpeedoQLConstants.NEQ: 177 ret = new NotEqual((Expression) child1, (Expression) child2); 178 break; 179 case SpeedoQLConstants.LT: 180 ret = new Lower((Expression) child1, (Expression) child2); 181 break; 182 case SpeedoQLConstants.GT: 183 ret = new Greater((Expression) child1, (Expression) child2); 184 break; 185 case SpeedoQLConstants.GTE: 186 ret = new GreaterEqual((Expression) child1, (Expression) child2); 187 break; 188 case SpeedoQLConstants.LTE: 189 ret = new LowerEqual((Expression) child1, (Expression) child2); 190 break; 191 } 192 if (debug) { 193 logger.log(BasicLevel.DEBUG, "push(" + ret + ")"); 194 } 195 stack.push(ret); 196 } 197 } 198 } 199 if (debug) { 200 logger.log(BasicLevel.DEBUG, "children:" + node.jjtGetNumChildren() 201 + " / stack: " + stack.size()); 202 logger.log(BasicLevel.DEBUG, tab + "End of Visit RelationalExpression: " + node); 203 } 204 return null; 205 } 206 207 public Object visit(ASTAdditiveExpression node, Object data) { 208 logger.log(BasicLevel.DEBUG, tab + "Visit AdditiveExpression: " + node); 209 tab += '\t'; 210 visit((SimpleNode) node, data); 211 tab = tab.substring(1); 212 Stack stack = (Stack ) data; 213 if (stack.size() > 0) { 214 Expression ret = (Expression) stack.pop(); 215 for (int i = 0; i < node.jjtGetNumChildren() - 1; i++) { 216 logger.log(BasicLevel.DEBUG, "Visit AdditiveExpression... children...[" + i + "]"); 217 218 switch (((Integer ) node.ops.get(node.jjtGetNumChildren() - 2 - i)).intValue()) { 219 220 case SpeedoQLConstants.PLUS: 221 ret = new Plus((Expression) stack.pop(), ret); 222 break; 223 case SpeedoQLConstants.MINUS: 224 ret = new Minus((Expression) stack.pop(), ret); 225 break; 226 case SpeedoQLConstants.MULT: 227 ret = new Mult((Expression) stack.pop(), ret); 228 break; 229 case SpeedoQLConstants.DIV: 230 ret = new DivideBy((Expression) stack.pop(), ret); 231 break; 232 default: 233 234 } 235 } 236 ((Stack ) data).push(ret); 237 } 238 logger.log(BasicLevel.DEBUG, tab + "End of Visit AdditiveExpression: " + node); 239 return null; 240 } 241 242 public Object visit(ASTUnaryExpression node, Object data) { 243 logger.log(BasicLevel.DEBUG, tab + "Visit UnaryExpression" + node); 244 tab += '\t'; 245 visit((SimpleNode) node, data); 246 tab = tab.substring(1); 247 Stack stack = (Stack ) data; 248 if (stack.size() > 0) { 249 Object o = stack.pop(); 250 if (node.ops.size() > 0) { 251 switch (((Integer ) node.ops.get(0)).intValue()) { 252 case SpeedoQLConstants.MINUS: 253 o = new UMinus((Expression) o); 254 break; 255 case SpeedoQLConstants.BITWISECOMPL: 256 o = new Bitwize((Expression) o); 257 break; 258 case SpeedoQLConstants.NOT: 259 logger.log(BasicLevel.DEBUG, "NOT(" + o + "): " + node); 260 o = new Not((Expression) o); 261 break; 262 } 263 } 264 ((Stack ) data).push(o); 265 } 266 logger.log(BasicLevel.DEBUG, tab + "End of Visit UnaryExpression: " + node); 267 return null; 268 } 269 270 public Object visit(ASTCastExpression node, Object data) { 271 return null; 272 } 273 274 public Object visit(ASTArgumentList node, Object data) { 275 return null; 276 } 277 278 public Object visit(ASTLiteral node, Object data) { 279 if (node.value instanceof Integer ) { 280 ((Stack ) data).push(new BasicOperand(((Integer ) node.value).intValue())); 281 } else if (node.value instanceof Float ) { 282 ((Stack ) data).push(new BasicOperand(((Float ) node.value).floatValue())); 283 } else if (node.value instanceof Character ) { 284 ((Stack ) data).push(new BasicOperand(((Character ) node.value).charValue())); 285 } else if (node.value instanceof String ) { 286 String s = (String ) (node.value); 287 s = s.substring(1, s.length() - 1); 288 ((Stack ) data).push(new BasicOperand(s)); 289 } else if (node.value instanceof Boolean ) { 290 ((Stack ) data).push(new BasicOperand(((Boolean ) node.value).booleanValue())); 291 } 292 return null; 293 } 294 295 public Object visit(ASTType node, Object data) { 296 logger.log(BasicLevel.DEBUG, "Visit Type: " + node); 297 return null; 298 } 299 300 public Object visit(ASTQualifiedName node, Object data) { 301 ((Stack ) data).push(new BasicOperand((String ) node.value)); 302 return null; 303 } 304 305 306 311 public Object visit(SimpleNode node) throws Exception { 312 return visit(node, new Stack ()); 313 } 314 315 318 public Object visit(SimpleNode node, Object data) { 319 return node.childrenAccept(this, data); 320 } 321 322 public Object visit(ASTSpeedoQL node, Object data) { 323 return null; 324 } 325 326 private boolean usedInRelationalExpresssion(int op) { 327 switch (op) { 328 case SpeedoQLConstants.OR: 329 case SpeedoQLConstants.AND: 330 case SpeedoQLConstants.BITWISEOR: 331 case SpeedoQLConstants.BITWISEXOR: 332 case SpeedoQLConstants.BITWISEAND: 333 case SpeedoQLConstants.EQ: 334 case SpeedoQLConstants.NEQ: 335 case SpeedoQLConstants.LT: 336 case SpeedoQLConstants.GT: 337 case SpeedoQLConstants.GTE: 338 case SpeedoQLConstants.LTE: 339 logger.log(BasicLevel.DEBUG, "node useful"); 340 return true; 341 default: 342 logger.log(BasicLevel.DEBUG, "node useless"); 343 return false; 344 } 345 } 346 347 } 348 351 357 private boolean isJormPredicate(Expression e) { 358 return isSimpleOperator(e) 359 || (e instanceof ConditionalAnd 360 && isJormPredicate(((Operator) e).getExpression(0)) 361 && isJormPredicate(((Operator) e).getExpression(1))); 362 } 363 364 private boolean isSimpleOperator(Expression e) { 365 boolean res = e instanceof Equal 366 || e instanceof Greater 367 || e instanceof GreaterEqual 368 || e instanceof Lower 369 || e instanceof LowerEqual; 370 if (res == false) { 371 return false; 372 } 373 Operator op = (Operator) e; 374 375 if (!(op.getExpression(0) instanceof Operand 376 && op.getExpression(1) instanceof Operand)) { 377 return false; 378 } 379 Operand o0 = (Operand) op.getExpression(0); 380 Operand o1 = (Operand) op.getExpression(1); 381 if (o0.getType().getTypeCode() == PTypeSpace.STRING.getTypeCode()) { 382 return true; 383 } else if (o1.getType().getTypeCode() == PTypeSpace.STRING.getTypeCode()) { 384 op.setExpression(0, o1); 386 op.setExpression(1, o0); 387 return true; 388 } else { 389 return false; 390 } 391 } 392 } 393 | Popular Tags |