- Timestamp:
- 07/19/07 17:39:55 (1 year ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
openmrs/branches/logic/src/api/org/openmrs/logic/LogicCriteria.java
r2016 r2033 4 4 5 5 import org.openmrs.Concept; 6 import org.openmrs.logic. datasource.LogicDataSource;6 import org.openmrs.logic.op.And; 7 7 import org.openmrs.logic.op.Operator; 8 import org.openmrs.logic.op.Or; 8 9 import org.openmrs.logic.rule.Rule; 9 10 … … 33 34 * <code>new LogicCriteria("CD4 COUNT").lt(200).within(Duration.months(6))</code> 34 35 * 35 * TODO: probably needs to be refactored to be more flexible36 36 */ 37 37 … … 44 44 private Operator operator = null; 45 45 46 private Object operand = null;47 48 private LogicCriteria next= null;46 private Object leftOperand = null; 47 48 private Object rightOperand = null; 49 49 50 50 /** … … 55 55 */ 56 56 public LogicCriteria(String token) { 57 this(token, null);57 rightOperand = token; 58 58 } 59 59 … … 65 65 */ 66 66 public LogicCriteria(String token, Object[] args) { 67 operand = token;67 rightOperand = token; 68 68 this.args = args; 69 69 } 70 70 71 /** 72 * A convenient constructor when a simple criteria is needed. 73 * 74 * For example: 75 * <code>new LogicCriteria("CD4 COUNT", Operator.LT, 200);</code> 76 * 77 * @param token a token used for the criteria 78 * @param operator an operator used for evaluating 79 * @param arg an argument used for the evaluation 80 */ 81 public LogicCriteria(String token, Operator operator, Object arg) { 82 this.operand = token; 71 private LogicCriteria(LogicCriteria left, Operator operator, Object right) { 72 if ((operator instanceof And || operator instanceof Or) 73 && right instanceof LogicCriteria) { 74 // Basic idea: 75 // - we make a new root AND or OR criteria 76 // - root.leftOperand = the root criteria of the left argument 77 // - root.rightOperand = the root criteria of the right argument 78 // - we make 'this' the same as the right argument, because we want 79 // the right argument to be the return value, so the user can 80 // continue envoking methods on that element 81 82 LogicCriteria root = null; 83 if (operator instanceof And) 84 root = new LogicCriteria(Operator.AND); 85 else 86 root = new LogicCriteria(Operator.OR); 87 88 // "rewind" up to the root element of the left argument, so that we 89 // can attach it to the AND or OR we're creating 90 LogicCriteria leftRoot = left; 91 while (leftRoot.parent != null) 92 leftRoot = leftRoot.parent; 93 94 root.leftOperand = leftRoot; 95 leftRoot.parent = root; 96 97 // "rewind" up to the root element of the left argument, so that we 98 // can attach it to the AND or OR we're creating 99 LogicCriteria rightRoot = (LogicCriteria) right; 100 while (rightRoot.parent != null) 101 rightRoot = rightRoot.parent; 102 103 root.rightOperand = rightRoot; 104 rightRoot.parent = root; 105 106 // we equalize this and right argument 107 this.parent = ((LogicCriteria) right).parent; 108 this.args = ((LogicCriteria) right).args; 109 this.operator = ((LogicCriteria) right).operator; 110 this.leftOperand = ((LogicCriteria) right).leftOperand; 111 this.rightOperand = ((LogicCriteria) right).rightOperand; 112 113 } else { 114 // in this case, "left" is the criteria to which we attach our newly 115 // created criteria 116 this.operator = operator; 117 this.rightOperand = right; 118 119 this.parent = left; 120 left.leftOperand = this; 121 } 122 } 123 124 private LogicCriteria(Operator operator, Object right) { 83 125 this.operator = operator; 84 this.args = new Object[] { arg }; 85 } 86 87 // Do we need this? I don't think so. ~vmitrovic 88 public LogicCriteria(LogicDataSource logicDataSource, Object id) { 89 operand = new Object[] { logicDataSource, id }; 90 this.args = null; 91 } 92 93 private LogicCriteria(LogicCriteria parent, Operator operator, 94 Object operand) { 95 this.parent = parent; 126 this.rightOperand = right; 127 } 128 129 private LogicCriteria(Operator operator) { 96 130 this.operator = operator; 97 this.operand = operand;98 131 } 99 132 … … 102 135 } 103 136 104 public LogicCriteria before(LogicCriteria criteria) {105 return new LogicCriteria(this, Operator.BEFORE, criteria);106 }107 108 137 public LogicCriteria after(Date value) { 109 return new LogicCriteria(this, Operator.BEFORE, value); 110 } 111 112 public LogicCriteria after(LogicCriteria criteria) { 113 return new LogicCriteria(this, Operator.BEFORE, criteria); 138 return new LogicCriteria(this, Operator.AFTER, value); 114 139 } 115 140 … … 183 208 184 209 public LogicCriteria lt(Integer value) { 185 return new LogicCriteria(this, Operator. GT, value);210 return new LogicCriteria(this, Operator.LT, value); 186 211 } 187 212 188 213 public LogicCriteria lt(Float value) { 189 return new LogicCriteria(this, Operator. GT, value);214 return new LogicCriteria(this, Operator.LT, value); 190 215 } 191 216 192 217 public LogicCriteria lt(String value) { 193 return new LogicCriteria(this, Operator. GT, value);218 return new LogicCriteria(this, Operator.LT, value); 194 219 } 195 220 196 221 public LogicCriteria lt(Date value) { 197 return new LogicCriteria(this, Operator. GT, value);222 return new LogicCriteria(this, Operator.LT, value); 198 223 } 199 224 200 225 public LogicCriteria lt(LogicCriteria criteria) { 201 return new LogicCriteria(this, Operator. GT, criteria);226 return new LogicCriteria(this, Operator.LT, criteria); 202 227 } 203 228 … … 234 259 } 235 260 236 public Object getOperand() {237 return operand;238 }239 240 public void setOperand(Object operand) {241 this.operand = operand;242 }243 244 261 public Operator getOperator() { 245 262 return operator; … … 258 275 } 259 276 277 public Object getLeftOperand() { 278 return leftOperand; 279 } 280 281 public void setLeftOperand(Object leftOperand) { 282 this.leftOperand = leftOperand; 283 } 284 285 public Object getRightOperand() { 286 return rightOperand; 287 } 288 289 public void setRightOperand(Object rightOperand) { 290 this.rightOperand = rightOperand; 291 } 292 260 293 public String getRootToken() { 261 LogicCriteria rootCriteria = this; 262 while (rootCriteria.getParent() != null) 263 rootCriteria = rootCriteria.getParent(); 264 return (String) rootCriteria.getOperand(); 265 } 266 267 /** 268 * Append another criteria to this criteria 269 * 270 * @param criteria 271 * @return <code>this</code> 272 */ 273 public LogicCriteria append(LogicCriteria criteria) { 274 // traverse the linked list of criterias and find the last criteria 275 LogicCriteria last = this; 276 while (true) { 277 if (last.next == null) { 278 last.next = criteria; 279 break; 280 } else 281 last = last.next; 282 } 283 284 return this; 294 return (String) getRootCriteria().rightOperand; 295 } 296 297 public LogicCriteria getRootCriteria() { 298 LogicCriteria root = this; 299 while (root.parent != null) 300 root = root.parent; 301 return root; 285 302 } 286 303 … … 294 311 } 295 312 313 public String toString() { 314 return "[" + leftOperand + " " + operator + " " + rightOperand + "]"; 315 } 316 317 // TODO delete when through with testing 318 public static void main(String[] args) { 319 LogicCriteria crit = new LogicCriteria("CD4 COUNT").not().contains(30); 320 System.out.println(crit.getRootCriteria()); 321 322 crit = new LogicCriteria("CD4 COUNT").not().contains(30).and( 323 new LogicCriteria("SOMETHING").lt(5)); 324 System.out.println(crit.getRootCriteria()); 325 } 326 296 327 }