001/**
002 * Copyright 2005-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krms.tree;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.util.tree.Node;
020import org.kuali.rice.core.api.util.tree.Tree;
021import org.kuali.rice.krms.api.repository.proposition.PropositionType;
022import org.kuali.rice.krms.dto.PropositionEditor;
023import org.kuali.rice.krms.dto.RuleEditor;
024import org.kuali.rice.krms.tree.node.CompareTreeNode;
025import org.kuali.rice.krms.util.KRMSConstants;
026import org.kuali.rice.krms.util.PropositionTreeUtil;
027
028import java.util.List;
029
030/**
031 * Build a tree to display to different rules next to each other.
032 *
033 * Used on the compare lightbox in KRMS.
034 *
035 * @author Kuali Student Team
036 */
037public class RuleCompareTreeBuilder extends AbstractTreeBuilder{
038
039    private static final long serialVersionUID = 1L;
040
041    public Tree<CompareTreeNode, String> buildTree(RuleEditor firstElement, RuleEditor secondElement) {
042        Tree<CompareTreeNode, String> myTree = initCompareTree();
043        Node<CompareTreeNode, String> firstNode = myTree.getRootElement().getChildren().get(0);
044
045        //Add the nodes recursively.
046        addTreeNode(firstNode, getRootProposition(firstElement), getRootProposition(secondElement));
047
048        //Underline the first node in the preview.
049        if ((firstNode.getChildren() != null) && (firstNode.getChildren().size() > 0)){
050            Node<CompareTreeNode, String> childNode = firstNode.getChildren().get(0);
051            if(childNode.getData() != null){
052                CompareTreeNode compareTreeNode = childNode.getData();
053
054                if(firstElement != null) {
055                    if(firstElement.getProposition() != null) {
056                        if(firstElement.getProposition().getPropositionTypeCode().equals(PropositionType.COMPOUND.getCode())) {
057                            if(!compareTreeNode.getFirstElement().trim().isEmpty()){
058                                compareTreeNode.setFirstElement(compareTreeNode.getFirstElement() + ":");
059                            }
060                        }
061                    }
062                }
063
064                if(secondElement != null) {
065                    if(secondElement.getProposition() != null) {
066                        if(secondElement.getProposition().getPropositionTypeCode().equals(PropositionType.COMPOUND.getCode())) {
067                            if(!compareTreeNode.getSecondElement().trim().isEmpty()){
068                                compareTreeNode.setSecondElement(compareTreeNode.getSecondElement() + ":");
069                            }
070                        }
071                    }
072                }
073            }
074        }
075
076        return myTree;
077    }
078
079    protected PropositionEditor getRootProposition(RuleEditor rule){
080        if(rule!=null){
081            return rule.getPropositionEditor();
082        }
083        return null;
084    }
085
086    public static Tree<CompareTreeNode, String> initCompareTree() {
087        Tree<CompareTreeNode, String> myTree = new Tree<CompareTreeNode, String>();
088
089        Node<CompareTreeNode, String> rootNode = createCompareNode();
090        myTree.setRootElement(rootNode);
091
092        rootNode.getChildren().add(createCompareNode());
093
094        return myTree;
095    }
096
097    private static Node<CompareTreeNode, String> createCompareNode() {
098        Node<CompareTreeNode, String> rootNode = new Node<CompareTreeNode, String>();
099        rootNode.setNodeType(KRMSConstants.NODE_TYPE_SUBRULEELEMENT);
100        rootNode.setData(new CompareTreeNode());
101        return rootNode;
102    }
103
104    protected void addTreeNode(Node<CompareTreeNode, String> currentNode, PropositionEditor firstElement, PropositionEditor secondElement) {
105        if ((firstElement == null) && (secondElement == null)) {
106            return;
107        }
108
109        Node<CompareTreeNode, String> newNode = new Node<CompareTreeNode, String>();
110        CompareTreeNode tNode = new CompareTreeNode(this.getDescription(firstElement), this.getDescription(secondElement));
111        tNode.setFirstElementItems(this.getListItems(firstElement));
112        tNode.setSecondElementItems(this.getListItems(secondElement));
113        newNode.setNodeType(KRMSConstants.NODE_TYPE_SUBRULEELEMENT);
114        if (!tNode.getFirstElement().equals(tNode.getSecondElement())){
115            addNodeType(newNode, KRMSConstants.NODE_TYPE_COMPAREELEMENT);
116        }
117
118        newNode.setData(tNode);
119        currentNode.getChildren().add(newNode);
120
121        this.addCompoundTreeNode(newNode, firstElement, secondElement);
122    }
123
124    protected void addCompoundTreeNode(Node<CompareTreeNode, String> newNode, PropositionEditor firstElement, PropositionEditor secondElement) {
125
126        // Retrieve the opreator code of the propositions
127        String firstOpCode = this.getLabelForOperator(firstElement);
128        String secondOpCode = this.getLabelForOperator(secondElement);
129
130        // Get the size of the biggest children list
131        int size = Math.max(getChildrenSize(firstElement), getChildrenSize(secondElement));
132
133        for (int i = 0; i < size; i++) {
134
135            PropositionEditor first = getChildForIndex(firstElement, i);
136            PropositionEditor second = getChildForIndex(secondElement, i);
137
138            // add an opcode node in between each of the children.
139            if (i>0) {
140                this.addOperatorTreeNode(newNode, getLabelForChild(first, firstOpCode), getLabelForChild(second, secondOpCode));
141            }
142
143            // call to build the childs node
144            addTreeNode(newNode, first, second);
145        }
146
147    }
148
149    protected String getLabelForChild(PropositionEditor proposition, String label){
150        if (proposition!=null){
151            return label;
152        }
153        return StringUtils.EMPTY;
154    }
155
156    protected String getLabelForOperator(PropositionEditor proposition){
157        if(proposition!=null){
158            return PropositionTreeUtil.getLabelForOperator(proposition.getCompoundOpCode());
159        }
160        return " ";
161    }
162
163    protected int getChildrenSize(PropositionEditor parent) {
164        if ((parent != null) && (parent.getCompoundComponents()!=null)){
165            return parent.getCompoundEditors().size();
166        }
167        return 0;
168    }
169
170    protected PropositionEditor getChildForIndex(PropositionEditor parent, int index) {
171        if ((parent != null) && (parent.getCompoundComponents()!=null)){
172            if(parent.getCompoundComponents().size() > index){
173                return parent.getCompoundEditors().get(index);
174            }
175        }
176        return null;
177    }
178
179    protected void addOperatorTreeNode(Node<CompareTreeNode, String> newNode, String firstElement, String secondElement) {
180        Node<CompareTreeNode, String> opNode = new Node<CompareTreeNode, String>();
181        if (!firstElement.equals(secondElement)){
182            opNode.setNodeType(KRMSConstants.NODE_TYPE_COMPAREELEMENT);
183        }
184        opNode.setData(new CompareTreeNode(firstElement, secondElement));
185        newNode.getChildren().add(opNode);
186    }
187
188    public List<String> getListItems(PropositionEditor propositionEditor) {
189        return null;
190    }
191
192    public String getNaturalLanguageUsageKey(){
193        return null;
194    }
195
196}