001    package org.kuali.rice.krms.tree;
002    
003    import org.apache.commons.lang.StringEscapeUtils;
004    import org.apache.commons.lang.StringUtils;
005    import org.kuali.rice.core.api.util.tree.Node;
006    import org.kuali.rice.core.api.util.tree.Tree;
007    import org.kuali.rice.krms.api.repository.language.NaturalLanguageUsage;
008    import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
009    import org.kuali.rice.krms.api.repository.proposition.PropositionType;
010    import org.kuali.rice.krms.dto.PropositionEditor;
011    import org.kuali.rice.krms.dto.RuleEditor;
012    import org.kuali.student.enrollment.class1.krms.dto.EnrolPropositionEditor;
013    import org.kuali.student.enrollment.class1.krms.tree.node.KSCompoundOpCodeNode;
014    import org.kuali.student.enrollment.class1.krms.tree.node.KSCompoundPropositionEditNode;
015    import org.kuali.student.enrollment.class1.krms.tree.node.KSSimplePropositionEditNode;
016    import org.kuali.student.enrollment.class1.krms.tree.node.KSSimplePropositionNode;
017    import org.kuali.student.enrollment.class1.krms.dto.EnrolRuleEditor;
018    import org.kuali.rice.krms.tree.node.RuleEditorTreeNode;
019    import org.kuali.student.enrollment.class2.courseoffering.service.decorators.PermissionServiceConstants;
020    import 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     */
029    public 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    }