1 23 24 package org.objectweb.medor.query.lib; 25 26 import org.objectweb.jorm.type.api.PType; 27 import org.objectweb.medor.api.Field; 28 import org.objectweb.medor.api.MedorException; 29 import org.objectweb.medor.clone.api.Cloneable; 30 import org.objectweb.medor.expression.api.Expression; 31 import org.objectweb.medor.expression.api.Operator; 32 import org.objectweb.medor.filter.api.FieldOperand; 33 import org.objectweb.medor.query.api.CalculatedField; 34 import org.objectweb.medor.query.api.NestedField; 35 import org.objectweb.medor.query.api.PropagatedField; 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.tuple.api.TupleLoader; 40 import org.objectweb.util.monolog.api.BasicLevel; 41 42 import java.util.ArrayList ; 43 import java.util.HashSet ; 44 import java.util.Iterator ; 45 import java.util.Map ; 46 47 53 public abstract class BasicQueryNode extends BasicQueryTree 54 implements QueryNode { 55 56 protected ArrayList children = new ArrayList (); 57 protected HashSet inner = new HashSet (); 58 protected TupleLoader tupleLoader = null; 59 protected Expression filter = null; 60 64 protected int[] indexes; 65 66 public BasicQueryNode() { 67 } 68 69 public BasicQueryNode(String name) { 70 super(name); 71 } 72 73 public Object clone(Object clone, 74 Map obj2clone) throws CloneNotSupportedException { 75 clone = super.clone(clone, obj2clone); 76 BasicQueryNode bqn = (BasicQueryNode) clone; 77 bqn.filter = (Expression) getClone(filter, obj2clone); 78 bqn.tupleLoader = tupleLoader; 79 bqn.children = new ArrayList (children.size()); 80 for(int i=0; i<children.size(); i++) { 81 bqn.children.add(getClone((Cloneable ) children.get(i), obj2clone)); 82 } 83 bqn.inner = new HashSet (inner.size()); 84 for (Iterator it = inner.iterator(); it.hasNext(); ) { 85 bqn.inner.add(getClone((Cloneable ) it.next(), obj2clone)); 86 } 87 if (indexes != null) { 88 bqn.indexes = new int[indexes.length]; 89 System.arraycopy(indexes, 0, bqn.indexes, 0, indexes.length); 90 } 91 return clone; 92 } 93 94 103 public PropagatedField addPropagatedField(String name, PType type, 104 QueryTreeField[] anc) 105 throws MedorException { 106 String fn = getFieldName(this.name, name); 107 if (name2field.containsKey(fn)) 108 throw new MedorException("Two fields with the same name: " + fn); 109 PropagatedField newField = new BasicPropagatedField(fn, type, this, anc); 110 this.addField(newField); 112 for (int i = 0; i < anc.length; i++) { 114 addChild(anc[i].getQueryTree()); 115 } 116 return newField; 117 } 118 119 128 public CalculatedField addCalculatedField(String name, PType type, 129 Expression exp) 130 throws MedorException { 131 String fn = getFieldName(this.name, name); 132 if (name2field.containsKey(fn)) 133 throw new MedorException("Two fields with the same name: " + fn); 134 CalculatedField newField = new BasicCalculatedField(fn, type, this, exp); 135 this.addField(newField); 136 addChildrenFromExpression(exp); 139 return newField; 140 } 141 142 148 public QueryTreeField removeField(String name) throws MedorException { 149 boolean debug = logger != null && logger.isLoggable(BasicLevel.DEBUG); 150 if (debug) { 151 logger.log(BasicLevel.DEBUG, "QueryNode: Removing field " + name); 152 } 153 Field toRemove = this.getField(name); 154 if (debug) { 155 logger.log(BasicLevel.DEBUG, "Found the field " + toRemove); 156 } 157 if (removeField(toRemove)) { 158 updateChildren(); 161 return (QueryTreeField)toRemove; 162 } 163 else return null; 164 } 165 166 public QueryTree[] getChildren() { 167 boolean debug = logger != null && logger.isLoggable(BasicLevel.DEBUG); 168 if (debug) logger.log(BasicLevel.DEBUG, "Calculating children for QueryNode " + this); 169 QueryTree[] theChildren = (QueryTree[]) children.toArray(new QueryTree[0]); 170 if (debug) { 171 logger.log(BasicLevel.DEBUG, "Found " + theChildren.length + " child(ren)"); 172 for (int i = 0; i < theChildren.length; i++) { 173 logger.log(BasicLevel.DEBUG, "Child: " + theChildren[i]); 174 } 175 } 176 return theChildren; 177 } 178 179 public boolean isOuter(QueryTree child) { 180 if (!children.contains(child)) { 181 throw new IllegalArgumentException ("not a child: " + child); 182 } 183 return !inner.contains(child); 184 } 185 186 public void setOuter(QueryTree child, boolean value) { 187 if (!children.contains(child)) { 188 throw new IllegalArgumentException ("not a child: " + child); 189 } 190 if (value) { 191 inner.remove(child); 192 } else { 193 inner.add(child); 194 } 195 } 196 197 public QueryTreeField replace(QueryTreeField old, QueryTreeField neo) { 198 boolean debug = logger != null && logger.isLoggable(BasicLevel.DEBUG); 199 if (debug) logger.log(BasicLevel.DEBUG, "Replacing field"); 200 201 int idx = this.fields.indexOf(old); 202 if (idx == -1) { 203 if (debug) logger.log(BasicLevel.DEBUG, "Have not found field " + old); 204 return null; 205 } 206 fields.set(idx, neo); 207 name2field.remove(old.getName()); 208 name2field.put(neo.getName(), neo); 209 updateChildren(); 210 return old; 211 } 212 213 217 public void setQueryFilter(Expression filter) 218 throws UnsupportedOperationException { 219 this.filter = filter; 220 updateChildren(); 223 } 224 225 public Expression getQueryFilter() { 226 return filter; 227 } 228 229 public abstract short getType(); 230 231 public TupleLoader getTupleLoader() { 232 return tupleLoader; 233 } 234 235 public void setTupleLoader(TupleLoader loader) { 236 tupleLoader = loader; 237 } 238 239 public void updatePropagatedField(String name, QueryTreeField[] previous) 240 throws MedorException { 241 Field f = (Field) name2field.get(name); 242 if (f ==null) 243 throw new MedorException("No field found"); 244 if (!(f instanceof PropagatedField)) 245 throw new MedorException("Bad type: " + f.getClass().getName()); 246 ((PropagatedField) f).replacePreviousField(previous); 247 updateChildren(); 248 } 249 250 public void updateCalculatedField(String name, Expression e) 251 throws MedorException { 252 Field f = (Field) name2field.get(name); 253 if (f ==null) 254 throw new MedorException("No field found"); 255 if (!(f instanceof CalculatedField)) 256 throw new MedorException("Bad type: " + f.getClass().getName()); 257 ((CalculatedField) f).setExpression(e); 258 updateChildren(); 259 } 260 261 265 protected synchronized void addField(Field f) { 266 name2field.put(f.getName(), f); 267 fields.add(f); 268 } 269 270 276 private boolean removeField(Field f) { 277 if (name2field.remove(f.getName()) == null) 278 return false; 279 else { 280 fields.remove(f); 281 return true; 282 } 283 } 284 285 289 protected void updateChildren() { 290 children.clear(); 291 Field[] fs = this.getFields(); 292 for (int i = 0; i < fs.length; i++) { 294 if (fs[i] instanceof PropagatedField) { 295 Field[] anc = ((PropagatedField)fs[i]).getPreviousFields(); 296 for (int j = 0; j < anc.length; j++) { 297 addChild(((QueryTreeField)anc[j]).getQueryTree()); 298 } 299 } 300 else if (fs[i] instanceof NestedField) { 301 Field[] grouped = ((NestedField)fs[i]).getFields(); 302 for (int j = 0; j < grouped.length; j++) { 303 addChild(((QueryTreeField)grouped[j]).getQueryTree()); 304 } 305 } 306 else if (fs[i] instanceof CalculatedField) { 307 addChildrenFromExpression(((CalculatedField)fs[i]).getExpression()); 308 } 309 } 310 addChildrenFromExpression(this.getQueryFilter()); 311 } 312 313 318 private void addChildrenFromExpression(Expression exp) { 319 if (exp instanceof FieldOperand) { 320 addChild(((QueryTreeField)((FieldOperand)exp).getField()).getQueryTree()); 321 } 322 else if (exp instanceof Operator) { 323 Operator op = (Operator) exp; 324 for (int i=0; i<op.getOperandNumber(); i++) { 325 addChildrenFromExpression(op.getExpression(i)); 326 } 327 } 328 } 329 330 protected String getFieldName(String nodeName, String fieldName) { 331 if (nodeName==null || nodeName.length()==0) 332 return fieldName; 333 else 334 return nodeName + "." + fieldName; 335 } 336 337 protected void addChild(QueryTree qt) { 338 if (!children.contains(qt)) { 339 children.add(qt); 340 } 341 } 342 } 343 | Popular Tags |