1 23 24 package org.objectweb.medor.optim.lib; 25 26 import org.objectweb.medor.api.MedorException; 27 import org.objectweb.medor.expression.api.BinaryOperator; 28 import org.objectweb.medor.expression.api.Expression; 29 import org.objectweb.medor.expression.api.Operator; 30 import org.objectweb.medor.expression.lib.And; 31 import org.objectweb.medor.expression.lib.ConditionalAnd; 32 import org.objectweb.medor.filter.api.FieldOperand; 33 import org.objectweb.medor.query.api.CalculatedField; 34 import org.objectweb.medor.query.api.FilteredQueryTree; 35 import org.objectweb.medor.query.api.PropagatedField; 36 import org.objectweb.medor.query.api.QueryLeaf; 37 import org.objectweb.medor.query.api.QueryNode; 38 import org.objectweb.medor.query.api.QueryTree; 39 import org.objectweb.medor.query.api.QueryTreeField; 40 import org.objectweb.medor.query.lib.Project; 41 import org.objectweb.util.monolog.api.BasicLevel; 42 43 import java.util.HashMap ; 44 import java.util.Map ; 45 46 49 public class PushSelectionRule extends BasicRule { 50 51 public class SameQT { 52 public boolean isSame; 53 public QueryTree qt; 54 55 public SameQT(boolean i, QueryTree q) { 56 isSame = i; 57 qt = q; 58 } 59 public SameQT() { 60 } 61 } 62 63 public PushSelectionRule() { 64 super("PushSelectionRule"); 65 } 66 67 public QueryTree rewrite(QueryTree qt, QueryNode parent) throws MedorException { 68 debug = log != null && log.isLoggable(BasicLevel.DEBUG); 69 rewriteExp(qt, null); 70 return qt; 71 } 72 73 protected void rewriteExp(QueryTree qt, Expression addedExp) throws MedorException { 74 if (debug) log.log(BasicLevel.DEBUG, "****(qt=" + qt + ", addedExp="+ addedExp + ")"); 75 if (!(qt instanceof QueryLeaf)) { 76 addedExp = goDownFieldOperand(addedExp).e; 78 } 79 if (debug) log.log(BasicLevel.DEBUG, "addedExp="+ addedExp); 80 81 FilteredQueryTree fqt = null; 82 ModifiedExpression me = null; 83 if (qt instanceof FilteredQueryTree && qt.getClass()!=Project.class) { 84 fqt = (FilteredQueryTree) qt; 85 me = merge(fqt.getQueryFilter(), addedExp, 1); 87 88 if (qt instanceof QueryLeaf) { 89 if (me.isModified) 90 fqt.setQueryFilter(me.e); 91 return; 95 } 96 } 97 else { 98 me = new ModifiedExpression(); 99 me.e = addedExp; 100 } 101 102 Map qt2e = new HashMap (); 103 me = extractMapFromExpression(me.e, qt2e, 0); 104 if (debug) log.log(BasicLevel.DEBUG, "me.isModified="+ me.isModified); 105 if (debug) log.log(BasicLevel.DEBUG, "fqt="+ fqt); 106 if (me.isModified && fqt!=null) { 107 fqt.setQueryFilter(me.e); 110 } 111 QueryTree[] qts = ((QueryNode) qt).getChildren(); 112 for (int i=0; i<qts.length; i++) { 113 rewriteExp(qts[i], (Expression) qt2e.get(qts[i])); 116 } 117 } 118 119 128 public ModifiedExpression merge(Expression origin, Expression addExp, int op) { 129 ModifiedExpression result = new ModifiedExpression(); 130 if (debug) log.log(BasicLevel.DEBUG, "Merge(" + origin + ", " + addExp + ", " + op + ")"); 131 if (addExp == null) { 132 result.e = origin; 133 result.isModified = false; 134 } else if (origin == null) { 135 result.e = addExp; 136 result.isModified = true; 137 } else { 138 if (op == 2) 139 result.e = new ConditionalAnd(origin, addExp); 140 else 141 result.e = new And(origin, addExp); 142 result.isModified = true; 143 } 144 return result; 145 } 146 147 158 public ModifiedExpression extractMapFromExpression( 159 Expression e, Map qt2e, int op) throws MedorException { 160 ModifiedExpression result = new ModifiedExpression(); 161 if (debug) log.log(BasicLevel.DEBUG, "extractMapFromExpression(" + e + ")"); 162 if (e == null) { 163 result.e = e; 164 result.isModified = false; 165 } else if (e instanceof And || e instanceof ConditionalAnd) { 166 int curOp = (e instanceof And ? 1 : 2); 167 ModifiedExpression l = extractMapFromExpression( 168 ((BinaryOperator) e).getExpression(0), qt2e, curOp); 169 ModifiedExpression r = extractMapFromExpression( 170 ((BinaryOperator) e).getExpression(1), qt2e, curOp); 171 172 if (l.e == null) { 173 result.isModified = true; 175 result.e = r.e; 176 } else if (r.e == null) { 177 result.isModified = true; 179 result.e = l.e; 180 } else { 181 result.e = e; 184 result.isModified = false; 186 if (l.isModified) { 187 ((BinaryOperator) e).setExpression(0, l.e); 189 result.isModified = true; 190 } 191 if (r.isModified) { 192 ((BinaryOperator) e).setExpression(1, r.e); 194 result.isModified = true; 195 result.e = e; 196 } 197 } 198 } else { 199 SameQT sqt = isSameQT(e); 202 if (sqt.isSame) { 203 if (debug) log.log(BasicLevel.DEBUG, "extractMapFromExpression: same QT: sqt.qt=" + sqt.qt); 205 ModifiedExpression me = merge((Expression) qt2e.get(sqt.qt), e, op); 206 qt2e.put(sqt.qt, me.e); 207 result.isModified = true; 210 result.e = null; 211 } else { 212 if (debug) log.log(BasicLevel.DEBUG, "extractMapFromExpression: not same QT:"); 213 result.isModified = false; 216 result.e = e; 217 } 218 } 219 return result; 220 } 221 222 232 public SameQT isSameQT(Expression e) throws MedorException { 233 if (debug) log.log(BasicLevel.DEBUG, "isSameQT(" + e +")"); 234 if (e instanceof Operator) { 235 Operator op = (Operator) e; 236 SameQT res = new SameQT(); 237 res.isSame = true; 238 SameQT c = null; 239 for (int i=0; i<op.getOperandNumber() && res.isSame; i++) { 240 c = isSameQT(((Operator) e).getExpression(i)); 241 if (debug) log.log(BasicLevel.DEBUG, "isSameQT(): c.isSame=" + c.isSame); 242 if (debug) log.log(BasicLevel.DEBUG, "isSameQT(): c.qt=" + c.qt); 243 res.isSame &= c.isSame; 244 if (res.qt == null) { 245 res.qt = c.qt; 246 } else if (c.qt != null) 247 res.isSame &= (c.qt == res.qt); 248 } 249 return res; 250 } else if (e instanceof FieldOperand) { 251 QueryTree qtChild = ((QueryTreeField) ((FieldOperand) e).getField()) 252 .getQueryTree(); 253 return new SameQT(true, qtChild); 254 } else { 255 return new SameQT(true, null); 256 } 257 } 258 259 public ModifiedExpression goDownFieldOperand(Expression e) 260 throws MedorException { 261 ModifiedExpression me = new ModifiedExpression(); 262 me.e = e; 263 me.isModified = false; 264 if (e instanceof Operator) { 265 if (debug) log.log(BasicLevel.DEBUG, "Operator " + e); 266 Operator op = (Operator) e; 267 for (int i=0; i<op.getOperandNumber(); i++) { 268 me = goDownFieldOperand(op.getExpression(i)); 269 if (me.isModified) 270 op.setExpression(i, me.e); 271 } 272 me.e = e; 274 me.isModified = false; 275 } else if (e instanceof FieldOperand) { 276 if (debug) log.log(BasicLevel.DEBUG, "FieldOperand " + e); 277 FieldOperand fo = (FieldOperand) e; 278 QueryTreeField f = (QueryTreeField) fo.getField(); 279 if (f.getQueryTree() instanceof QueryLeaf) { 280 if (debug) log.log(BasicLevel.DEBUG, "FieldOperand QueryLeaf"); 281 } else if (f instanceof PropagatedField) { 286 if (debug) log.log(BasicLevel.DEBUG, "FieldOperand PropagatedField " + f); 287 fo.setField(((PropagatedField) f).getPreviousFields()[0]); 289 } else if (f instanceof CalculatedField) { 292 if (debug) log.log(BasicLevel.DEBUG, "FieldOperand CalculatedField" + f); 293 me.e = ((CalculatedField) e).getExpression(); 295 me.isModified = true; 296 } else 297 throw new MedorException("Impossible move other type:" + f); 298 } 299 return me; 300 } 301 } | Popular Tags |