001package org.kuali.rice.krms.tree;
002
003import org.apache.commons.lang.StringEscapeUtils;
004import org.apache.commons.lang.StringUtils;
005import org.kuali.rice.core.api.util.tree.Node;
006import org.kuali.rice.core.api.util.tree.Tree;
007import org.kuali.rice.krms.api.repository.language.NaturalLanguageUsage;
008import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
009import org.kuali.rice.krms.api.repository.proposition.PropositionType;
010import org.kuali.rice.krms.dto.PropositionEditor;
011import org.kuali.rice.krms.dto.RuleEditor;
012import org.kuali.student.enrollment.class1.krms.dto.EnrolPropositionEditor;
013import org.kuali.student.enrollment.class1.krms.tree.node.KSCompoundOpCodeNode;
014import org.kuali.student.enrollment.class1.krms.tree.node.KSCompoundPropositionEditNode;
015import org.kuali.student.enrollment.class1.krms.tree.node.KSSimplePropositionEditNode;
016import org.kuali.student.enrollment.class1.krms.tree.node.KSSimplePropositionNode;
017import org.kuali.student.enrollment.class1.krms.dto.EnrolRuleEditor;
018import org.kuali.rice.krms.tree.node.RuleEditorTreeNode;
019import org.kuali.student.enrollment.class2.courseoffering.service.decorators.PermissionServiceConstants;
020import org.kuali.student.krms.naturallanguage.util.KsKrmsConstants;
021
022/**
023 * Created with IntelliJ IDEA.
024 * User: Peggy
025 * Date: 2/4/13
026 * Time: 3:26 PM
027 * To change this template use File | Settings | File Templates.
028 */
029public class RuleEditTreeBuilder extends AbstractTreeBuilder{
030
031    private static final long serialVersionUID = 1L;
032
033    public Tree buildTree(RuleEditor rule) {
034
035        Tree myTree = new Tree<RuleEditorTreeNode, String>();
036
037        Node<RuleEditorTreeNode, String> rootNode = new Node<RuleEditorTreeNode, String>();
038        myTree.setRootElement(rootNode);
039
040        PropositionEditor prop = (PropositionEditor) rule.getProposition();
041
042        if (prop != null){
043
044            addChildNode(rule, rootNode, prop);
045        }
046
047        return myTree;
048    }
049
050    /**
051     * This method builds a propositionTree recursively walking through the children of the proposition.
052     *
053     * @param sprout - parent tree node
054     * @param prop   - PropositionBo for which to make the tree node
055     */
056    private void addChildNode(RuleEditor rule, Node sprout, PropositionEditor prop) {
057        // Depending on the type of proposition (simple/compound), and the editMode,
058        // Create a treeNode of the appropriate type for the node and attach it to the
059        // sprout parameter passed in.
060        // If the prop is a compound proposition, calls itself for each of the compoundComponents
061        if (prop != null) {
062            if (PropositionType.SIMPLE.getCode().equalsIgnoreCase(prop.getPropositionTypeCode())) {
063                // Simple Proposition
064                // add a node for the description display with a child proposition node
065                Node<RuleEditorTreeNode, String> child = new Node<RuleEditorTreeNode, String>();
066
067                // Simple Proposition add a node for the description display with a child proposition node
068                if (prop.isEditMode()) {
069                    child.setNodeType(KSSimplePropositionEditNode.NODE_TYPE);
070                    KSSimplePropositionEditNode pNode = new KSSimplePropositionEditNode(prop);
071                    child.setData(pNode);
072                } else {
073                    child.setNodeLabel(this.buildNodeLabel(rule, prop));
074                    child.setNodeType(KSSimplePropositionNode.NODE_TYPE);
075                    KSSimplePropositionNode pNode = new KSSimplePropositionNode(prop);
076                    child.setData(pNode);
077                }
078                sprout.getChildren().add(child);
079            } else if (PropositionType.COMPOUND.getCode().equalsIgnoreCase(prop.getPropositionTypeCode())) {
080                // Compound Proposition
081                Node<RuleEditorTreeNode, String> aNode = new Node<RuleEditorTreeNode, String>();
082
083                // editMode has description as an editable field
084                if (prop.isEditMode()) {
085                    aNode.setNodeLabel("");
086                    aNode.setNodeType(KSCompoundPropositionEditNode.NODE_TYPE);
087                    KSCompoundPropositionEditNode pNode = new KSCompoundPropositionEditNode(prop);
088                    aNode.setData(pNode);
089                } else {
090                    aNode.setNodeLabel(this.buildNodeLabel(rule, prop));
091                    aNode.setNodeType(RuleEditorTreeNode.COMPOUND_NODE_TYPE);
092                    RuleEditorTreeNode pNode = new RuleEditorTreeNode(prop);
093                    aNode.setData(pNode);
094                }
095                sprout.getChildren().add(aNode);
096
097                int counter = 0;
098                for (PropositionEditor child : prop.getCompoundEditors()) {
099                    // add an opcode node in between each of the children.
100                    if (counter > 0) {
101                        addOpCodeNode(aNode, prop, counter);
102                    }
103                    counter++;
104                    // call to build the childs node
105                    addChildNode(rule, aNode, child);
106                }
107            }
108        }
109    }
110
111    protected String getDescription(PropositionEditor proposition) {
112
113        proposition.setDescription(super.getDescription(proposition));
114        return proposition.getDescription();
115    }
116
117    private String buildNodeLabel(RuleEditor rule, PropositionEditor prop) {
118        //Build the node label.
119        String prefix = this.getPropositionPrefix(rule, prop);
120        return prefix + StringEscapeUtils.escapeHtml(this.getDescription(prop));
121    }
122
123    /**
124     * This method adds an opCode Node to separate components in a compound proposition.
125     *
126     * @param currentNode
127     * @param prop
128     * @return
129     */
130    private void addOpCodeNode(Node currentNode, PropositionEditor prop, int counter) {
131        //Create the node.
132        Node<KSCompoundOpCodeNode, String> aNode = new Node<KSCompoundOpCodeNode, String>();
133        aNode.setNodeLabel("");
134        aNode.setNodeType("ruleTreeNode compoundOpCodeNode");
135
136        //Add a dummy editor.
137        PropositionEditor editor = new PropositionEditor();
138        editor.setKey(prop.getKey() + counter);
139        editor.setCompoundOpCode(prop.getCompoundOpCode());
140
141        aNode.setData(new KSCompoundOpCodeNode(editor));
142        currentNode.getChildren().add(aNode);
143    }
144
145    public String getNaturalLanguageUsageKey(){
146        return  KsKrmsConstants.KRMS_NL_RULE_EDIT;
147    }
148}