1 23 package org.objectweb.medor.optim.lib; 24 25 import org.objectweb.medor.api.Field; 26 import org.objectweb.medor.api.MedorException; 27 import org.objectweb.medor.expression.api.Expression; 28 import org.objectweb.medor.expression.api.Operator; 29 import org.objectweb.medor.filter.api.FieldOperand; 30 import org.objectweb.medor.filter.lib.ExpressionPrinter; 31 import org.objectweb.medor.query.api.CalculatedField; 32 import org.objectweb.medor.query.api.FilteredQueryTree; 33 import org.objectweb.medor.query.api.OrderField; 34 import org.objectweb.medor.query.api.PropagatedField; 35 import org.objectweb.medor.query.api.QueryLeaf; 36 import org.objectweb.medor.query.api.QueryNode; 37 import org.objectweb.medor.query.api.QueryTree; 38 import org.objectweb.medor.query.api.QueryTreeField; 39 import org.objectweb.medor.query.lib.Nest; 40 import org.objectweb.util.monolog.api.BasicLevel; 41 42 import java.util.HashMap ; 43 import java.util.HashSet ; 44 import java.util.Map ; 45 import java.util.Set ; 46 47 51 public class FlattenQueryTreeRule extends BasicRule { 52 53 public FlattenQueryTreeRule() { 54 super("FlattenQueryTreeRule"); 55 } 56 57 public QueryTree rewrite(QueryTree qt, QueryNode parent) 58 throws MedorException { 59 return flatten(parent, qt); 60 } 61 62 public QueryTree flatten(QueryNode parent, QueryTree qt) 63 throws MedorException { 64 if (qt instanceof QueryLeaf) { 65 return qt; 66 } 67 if (qt instanceof Nest) { 68 flatten((Nest) qt, ((QueryNode) qt).getChildren()[0]); 69 return qt; 70 } 71 QueryNode qn = (QueryNode) qt; 72 QueryTree[] children = qn.getChildren(); 73 Map localyReplaced = (parent == null ? null : new HashMap ()); 75 Set inner = findInner(qn); 76 while (containsQueryNode(children)) { 77 log.log(BasicLevel.DEBUG, "node"); 78 if (useParent(qn.getQueryFilter())) { 79 qn.setQueryFilter(qn.getQueryFilter()); 80 } 81 Field[] fs = qt.getTupleStructure().getFields(); 82 for (int i = 0; i < fs.length; i++) { 83 if (fs[i] instanceof PropagatedField) { 84 QueryTreeField childF = (QueryTreeField) 85 ((PropagatedField) fs[i]).getPreviousFields()[0]; 86 if (childF.getQueryTree() instanceof QueryLeaf) { 87 continue; 88 } 89 if (childF instanceof PropagatedField) { 90 qn.updatePropagatedField(fs[i].getName(), 91 new QueryTreeField[]{(QueryTreeField) 92 ((PropagatedField) childF).getPreviousFields()[0]}); 93 } else if (childF instanceof CalculatedField) { 94 qn.replace((QueryTreeField) fs[i], childF); 96 if (parent != null) { 97 localyReplaced.put(fs[i], childF); 98 } 99 } else { 100 throw new MedorException("Unmanaged child field: " 101 + childF); 102 } 103 } else if (fs[i] instanceof CalculatedField) { 104 CalculatedField cf = (CalculatedField) fs[i]; 105 if (useParent(cf.getExpression())) { 106 qn.updateCalculatedField( 107 cf.getName(), cf.getExpression()); 108 } 109 } else { 110 throw new MedorException("Unmanaged Field: " + fs[i]); 111 } 112 } 113 replaceUsage(parent, localyReplaced); 115 116 OrderField[] orderFields = qt.getOrderBy(); 119 if (orderFields != null) { 120 for (int i = 0; i < orderFields.length; i++) { 121 QueryTreeField orderField = orderFields[i].getField(); 122 if (debug) { 123 log.log(BasicLevel.DEBUG, "managing orderField " + orderField); 124 } 125 if (orderField.getQueryTree() instanceof QueryLeaf) { 127 if (debug) { 128 log.log(BasicLevel.DEBUG, "nothing to do for this field (already on a leaf) " + orderField); 129 } 130 continue; 131 } 132 if (orderField instanceof PropagatedField) { 133 QueryTreeField childF = (QueryTreeField) 134 ((PropagatedField) orderField) 135 .getPreviousFields()[0]; 136 if (childF.getQueryTree() instanceof QueryLeaf) { 137 continue; 138 } 139 if (childF instanceof PropagatedField) { 140 orderFields[i].setField( 142 (QueryTreeField) 143 ((PropagatedField) childF) 144 .getPreviousFields()[0]); 145 } else if (childF instanceof CalculatedField) { 146 orderFields[i].setField(childF); 148 } else { 149 throw new MedorException("Unmanaged child field: " 150 + childF); 151 } 152 } else if (orderField instanceof CalculatedField) { 153 CalculatedField cf = (CalculatedField) orderField; 154 if (useParent(cf.getExpression())) { 155 ((CalculatedField) orderField) 157 .setExpression(cf.getExpression()); 158 } 159 } else { 160 throw new MedorException("Unmanaged Field: " + orderField); 161 } 162 } 163 qt.setOrderBy(orderFields); 164 } 165 166 boolean modified = false; 168 Expression e = qn.getQueryFilter(); 169 for (int i = 0; i < children.length; i++) { 170 if (children[i] instanceof FilteredQueryTree) { 171 Expression filter = ((FilteredQueryTree) children[i]) 172 .getQueryFilter(); 173 if (filter != null) { 174 if (e == null) { 175 e = filter; 176 } else { 177 e = new org.objectweb.medor.expression.lib.And(e, filter); 178 } 179 modified = true; 180 } 181 } 182 } 183 if (modified) { 184 log.log(BasicLevel.DEBUG, "Filter modified: " + ExpressionPrinter.e2str(e)); 185 qn.setQueryFilter(e); 186 } 187 children = qn.getChildren(); 188 } 189 for (int i = 0; i < children.length; i++) { 190 qn.setOuter(children[i], !inner.contains(children[i])); 191 } 192 return qt; 193 } 194 195 private Set findInner(QueryTree qt) { 196 Set result = new HashSet (); 197 findInner(qt, false, result); 198 return result; 199 } 200 201 private void findInner(QueryTree qt, boolean inner, Set result) { 202 if (inner) { result.add(qt); } 203 if (qt instanceof QueryNode) { 204 QueryNode qn = (QueryNode) qt; 205 QueryTree[] children = qn.getChildren(); 206 for (int i = 0; i < children.length; i++) { 207 findInner(children[i], inner || !qn.isOuter(children[i]), result); 208 } 209 } 210 } 211 212 private boolean containsQueryNode(QueryTree[] qts) { 213 log.log(BasicLevel.DEBUG, "Entering containsQueryNode for " + qts.length + " QueryTrees."); 214 for (int i = 0; i < qts.length; i++) { 215 if (qts[i] instanceof QueryNode) { 216 log.log(BasicLevel.DEBUG, "Found QueryNode " + qts[i]); 217 return true; 218 } else { 219 log.log(BasicLevel.DEBUG, "Found other QueryTree " + qts[i]); 220 } 221 } 222 log.log(BasicLevel.DEBUG, "containsQueryNode: no QueryNode found. Exiting"); 223 return false; 224 } 225 226 private boolean useParent(Expression e) { 227 if (e instanceof Operator) { 228 int size = ((Operator) e).getOperandNumber(); 229 boolean res = false; 230 for (int i = 0; i < size; i++) { 231 res |= useParent(((Operator) e).getExpression(i)); 232 } 233 return res; 234 } else if (e instanceof FieldOperand) { 235 FieldOperand fo = (FieldOperand) e; 236 QueryTreeField f = (QueryTreeField) fo.getField(); 237 if (f.getQueryTree() instanceof QueryLeaf) { 238 return false; 239 } 240 if (f instanceof PropagatedField) { 241 fo.setField(((PropagatedField) f).getPreviousFields()[0]); 242 return true; 243 } else { 244 log.log(BasicLevel.ERROR, "Unmanaged FieldOperand: " + f); 245 } 246 } 247 return false; 248 } 249 250 } 251 | Popular Tags |