Downloads Documentation Community Contribute Demo






Show Sidebar
Login | Register
Show
Ignore:
Timestamp:
07/19/07 17:39:55 (1 year ago)
Author:
vmitrovic
Message:

Logic service - LogicCriteria now fully functional.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • openmrs/branches/logic/src/api/org/openmrs/logic/LogicCriteria.java

    r2016 r2033  
    44 
    55import org.openmrs.Concept; 
    6 import org.openmrs.logic.datasource.LogicDataSource
     6import org.openmrs.logic.op.And
    77import org.openmrs.logic.op.Operator; 
     8import org.openmrs.logic.op.Or; 
    89import org.openmrs.logic.rule.Rule; 
    910 
     
    3334 * <code>new LogicCriteria("CD4 COUNT").lt(200).within(Duration.months(6))</code> 
    3435 *  
    35  * TODO: probably needs to be refactored to be more flexible 
    3636 */ 
    3737 
     
    4444    private Operator operator = null; 
    4545 
    46     private Object operand = null; 
    47  
    48     private LogicCriteria next = null; 
     46    private Object leftOperand = null; 
     47 
     48    private Object rightOperand = null; 
    4949 
    5050    /** 
     
    5555     */ 
    5656    public LogicCriteria(String token) { 
    57         this(token, null)
     57        rightOperand = token
    5858    } 
    5959 
     
    6565     */ 
    6666    public LogicCriteria(String token, Object[] args) { 
    67         operand = token; 
     67        rightOperand = token; 
    6868        this.args = args; 
    6969    } 
    7070 
    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) { 
    83125        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) { 
    96130        this.operator = operator; 
    97         this.operand = operand; 
    98131    } 
    99132 
     
    102135    } 
    103136 
    104     public LogicCriteria before(LogicCriteria criteria) { 
    105         return new LogicCriteria(this, Operator.BEFORE, criteria); 
    106     } 
    107  
    108137    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); 
    114139    } 
    115140 
     
    183208 
    184209    public LogicCriteria lt(Integer value) { 
    185         return new LogicCriteria(this, Operator.GT, value); 
     210        return new LogicCriteria(this, Operator.LT, value); 
    186211    } 
    187212 
    188213    public LogicCriteria lt(Float value) { 
    189         return new LogicCriteria(this, Operator.GT, value); 
     214        return new LogicCriteria(this, Operator.LT, value); 
    190215    } 
    191216 
    192217    public LogicCriteria lt(String value) { 
    193         return new LogicCriteria(this, Operator.GT, value); 
     218        return new LogicCriteria(this, Operator.LT, value); 
    194219    } 
    195220 
    196221    public LogicCriteria lt(Date value) { 
    197         return new LogicCriteria(this, Operator.GT, value); 
     222        return new LogicCriteria(this, Operator.LT, value); 
    198223    } 
    199224 
    200225    public LogicCriteria lt(LogicCriteria criteria) { 
    201         return new LogicCriteria(this, Operator.GT, criteria); 
     226        return new LogicCriteria(this, Operator.LT, criteria); 
    202227    } 
    203228 
     
    234259    } 
    235260 
    236     public Object getOperand() { 
    237         return operand; 
    238     } 
    239  
    240     public void setOperand(Object operand) { 
    241         this.operand = operand; 
    242     } 
    243  
    244261    public Operator getOperator() { 
    245262        return operator; 
     
    258275    } 
    259276 
     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 
    260293    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; 
    285302    } 
    286303 
     
    294311    } 
    295312 
     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 
    296327}