001package org.kuali.rice.krms.tree;
002
003import org.apache.commons.lang.StringUtils;
004import org.kuali.rice.core.api.util.tree.Node;
005import org.kuali.rice.core.api.util.tree.Tree;
006import org.kuali.rice.krms.api.repository.LogicalOperator;
007import org.kuali.rice.krms.api.repository.proposition.PropositionDefinitionContract;
008import org.kuali.rice.krms.api.repository.proposition.PropositionType;
009import org.kuali.rice.krms.api.repository.rule.RuleDefinitionContract;
010import org.kuali.rice.krms.tree.node.CompareTreeNode;
011import org.kuali.student.krms.naturallanguage.util.KsKrmsConstants;
012
013import java.util.ArrayList;
014import java.util.List;
015
016/**
017 * Created with IntelliJ IDEA.
018 * User: Peggy
019 * Date: 2/4/13
020 * Time: 3:26 PM
021 * To change this template use File | Settings | File Templates.
022 */
023public class RuleCompareTreeBuilder extends AbstractTreeBuilder{
024
025    private static final long serialVersionUID = 1L;
026
027    public Tree<CompareTreeNode, String> buildTree(RuleDefinitionContract original, RuleDefinitionContract compare) {
028        Tree<CompareTreeNode, String> myTree = new Tree<CompareTreeNode, String>();
029
030        Node<CompareTreeNode, String> rootNode = new Node<CompareTreeNode, String>();
031        rootNode.setNodeType("subruleElement");
032        rootNode.setData(new CompareTreeNode());
033        myTree.setRootElement(rootNode);
034
035        Node<CompareTreeNode, String> firstNode = new Node<CompareTreeNode, String>();
036        firstNode.setNodeType("subruleElement");
037        firstNode.setData(new CompareTreeNode());
038        rootNode.getChildren().add(firstNode);
039
040        if (original != null) {
041            addTreeNode(firstNode, original.getProposition(), compare.getProposition());
042        }
043
044        //Underline the first node in the preview.
045        if ((firstNode.getChildren() != null) && (firstNode.getChildren().size() > 0)){
046            Node<CompareTreeNode, String> childNode = firstNode.getChildren().get(0);
047            if(childNode.getData() != null){
048                CompareTreeNode compareTreeNode = childNode.getData();
049                compareTreeNode.setOriginal(compareTreeNode.getOriginal() + ":");
050                compareTreeNode.setCompared(compareTreeNode.getCompared() + ":");
051            }
052        }
053
054        return myTree;
055    }
056
057    public static Tree<CompareTreeNode, String> initCompareTree() {
058        Tree<CompareTreeNode, String> myTree = new Tree<CompareTreeNode, String>();
059
060        Node<CompareTreeNode, String> rootNode = new Node<CompareTreeNode, String>();
061        rootNode.setNodeType("subruleElement");
062        rootNode.setData(new CompareTreeNode());
063        myTree.setRootElement(rootNode);
064
065        Node<CompareTreeNode, String> firstNode = new Node<CompareTreeNode, String>();
066        firstNode.setNodeType("subruleElement");
067        firstNode.setData(new CompareTreeNode());
068        rootNode.getChildren().add(firstNode);
069
070        return myTree;
071    }
072
073    private void addTreeNode(Node<CompareTreeNode, String> currentNode, PropositionDefinitionContract original, PropositionDefinitionContract compared) {
074        if ((original == null) && (compared == null)) {
075            return;
076        }
077
078        Node<CompareTreeNode, String> newNode = new Node<CompareTreeNode, String>();
079        CompareTreeNode tNode = new CompareTreeNode(this.getDescription(original), this.getDescription(compared));
080        tNode.setOriginalItems(this.getListItems(original));
081        tNode.setComparedItems(this.getListItems(compared));
082        if (tNode.getOriginal().equals(tNode.getCompared())){
083            newNode.setNodeType("subruleElement");
084        } else {
085            newNode.setNodeType("subruleElement compareElement");
086        }
087
088        newNode.setData(tNode);
089        currentNode.getChildren().add(newNode);
090
091        this.addCompoundTreeNode(newNode, original, compared);
092    }
093
094    private void addCompoundTreeNode(Node<CompareTreeNode, String> newNode, PropositionDefinitionContract original, PropositionDefinitionContract compared) {
095
096        // Retrieve the opreator code of the original proposition
097        String originalOpCode = this.getOpCode(original);
098
099        // Retrieve the opreator code of the compare to proposition
100        String compareOpCode = this.getOpCode(compared);
101
102        // Get the children form both nodes.
103        List<? extends PropositionDefinitionContract> originalChildren = getChildPropositions(original);
104        List<? extends PropositionDefinitionContract> comparedChildren = getChildPropositions(compared);
105
106        // Get the size of the biggest children list
107        int size = Math.max(originalChildren.size(), comparedChildren.size());
108
109        for (int i = 0; i < size; i++) {
110
111            // Get the original child proposition at current position
112            PropositionDefinitionContract originalChild = null;
113            if (originalChildren.size() > i){
114                originalChild = originalChildren.get(i);
115            } else {
116                originalOpCode = " ";
117            }
118
119            // Get the compare child proposition at current position
120            PropositionDefinitionContract compareChild = null;
121            if (comparedChildren.size() > i){
122                compareChild = comparedChildren.get(i);
123            } else {
124                compareOpCode = " ";
125            }
126            // add an opcode node in between each of the children.
127            if (i>0) {
128                this.addOperatorTreeNode(newNode, originalOpCode, compareOpCode);
129            }
130
131            // call to build the childs node
132            addTreeNode(newNode, originalChild, compareChild);
133        }
134
135    }
136
137    private List<? extends PropositionDefinitionContract> getChildPropositions(PropositionDefinitionContract parent) {
138        List<? extends PropositionDefinitionContract> children;
139        if ((parent != null) && (parent.getCompoundComponents()!=null)){
140            children = parent.getCompoundComponents();
141        } else {
142            children = new ArrayList<PropositionDefinitionContract>();
143        }
144        return children;
145    }
146
147    private String getOpCode(PropositionDefinitionContract proposition){
148
149        String operatorCode = " ";
150        if (proposition != null){
151            if (LogicalOperator.AND.getCode().equalsIgnoreCase(proposition.getCompoundOpCode())) {
152                operatorCode = "AND";
153            } else if (LogicalOperator.OR.getCode().equalsIgnoreCase(proposition.getCompoundOpCode())) {
154                operatorCode = "OR";
155            }
156        }
157        return operatorCode;
158    }
159
160    private void addOperatorTreeNode(Node<CompareTreeNode, String> newNode, String originial, String compared) {
161        Node<CompareTreeNode, String> opNode = new Node<CompareTreeNode, String>();
162        if (!originial.equals(compared)){
163            opNode.setNodeType("compareElement");
164        }
165        opNode.setData(new CompareTreeNode(originial, compared));
166        newNode.getChildren().add(opNode);
167    }
168
169    public List<String> getListItems(PropositionDefinitionContract propositionEditor) {
170        return null;
171    }
172
173    public String getNaturalLanguageUsageKey(){
174        return  KsKrmsConstants.KRMS_NL_RULE_EDIT;
175    }
176
177}