001    package org.kuali.student.common.messagebuilder.impl;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    
006    import org.kuali.student.common.messagebuilder.booleanmessage.ast.BooleanNode;
007    import org.kuali.student.common.messagebuilder.impl.exceptions.MessageBuilderException;
008    
009    /**
010     * This class creates success messages for boolean binary tree nodes.
011     */
012    public class SuccessMessageBuilder {
013            /** Boolean operators to use in creating the success message */
014            private BooleanOperators booleanOperators;
015    
016            /**
017             * Creates a success message builder with boolean operators to use in 
018             * building the success message.
019             * 
020             * @param bo Boolean operators to build success message
021             */
022            public SuccessMessageBuilder(BooleanOperators bo) {
023                    this.booleanOperators = bo;
024            }
025    
026            /**
027             * Builds and sets the success message for each of the boolean nodes 
028             * (binary tree) in the <code>nodeList</code>.
029             * 
030             * @param nodeList List of boolean nodes 
031             * @return Complete success message 
032             */
033            public String buildSuccessMessage(List<BooleanNode> nodeList) throws MessageBuilderException {
034                    // List must only contain one root node
035                    List<BooleanNode> rootNodeList = new ArrayList<BooleanNode>();
036                    for(BooleanNode node : nodeList) {
037                            if(node.getParent() == null) {
038                                    rootNodeList.add(node);
039                            }
040                            buildSuccessMessage(node);
041                    }
042                    if(rootNodeList.size() > 1) {
043                            throw new MessageBuilderException("Node list contains more than one root node: " + rootNodeList);
044                    }
045                    return rootNodeList.get(0).getNodeMessage();
046            }
047    
048            /**
049             * Builds and sets the success message for a single 
050             * boolean <code>node</code> (b-tree node).
051             * 
052             * @param node Boolean node
053             */
054            public String buildSuccessMessage(final BooleanNode node) {
055                    // AND node
056                    if(node.getLabel().equals("*")) {
057                            buildAndNodeSuccessMessage(node);
058                    } 
059                    // OR node
060                    else if(node.getLabel().equals("+")) {
061                            buildOr1NodeSuccessMessage(node);
062                            buildOr2NodeSuccessMessage(node);
063                    }
064                    return node.getNodeMessage();
065            }
066    
067            /**
068             * Builds a success message for an AND node (b-tree node) where 
069             * left node and right node are true.
070             * 
071             * @param node Boolean node
072             */
073            private void buildAndNodeSuccessMessage(BooleanNode node) {
074                    if(node.getLabel().equals("*") && 
075                                    node.getLeftNode() != null && 
076                                    node.getRightNode() != null &&
077                                    node.getLeftNode().getValue() == true && 
078                                    node.getRightNode().getValue() == true &&
079                                    node.getLeftNode().getNodeMessage() != null && 
080                                    node.getRightNode().getNodeMessage() != null) {
081                    String logMessage = node.getLeftNode().getNodeMessage() + " " + 
082                            this.booleanOperators.getAndOperator() + " " + 
083                            node.getRightNode().getNodeMessage();
084                            
085                            if(node.getParent() != null && 
086                                            ( (node.getLabel().equals("+") && 
087                                                            node.getParent().getLabel().equals("*")) || 
088                                                            (node.getLabel().equals("*") && 
089                                                                            node.getParent().getLabel().equals("+")))) {
090                                logMessage = "(" + logMessage + ")";
091                            }
092                            node.setNodeMessage(logMessage);
093                    }
094            }
095    
096            /**
097             * Builds a success message for an OR node (b-tree node) where 
098             * left node is true and right node is false or 
099             * left node is false and right node is true.
100             * 
101             * @param node Boolean node
102             */
103            private void buildOr1NodeSuccessMessage(BooleanNode node) {
104                    // OR1
105                    if(node.getLabel().equals("+") && 
106                                    node.getLeftNode() != null && 
107                                    node.getRightNode() != null &&
108                                    ((node.getLeftNode().getValue() == false && 
109                                                    node.getRightNode().getValue() == true && 
110                                                    node.getRightNode().getNodeMessage() != null ) || 
111                                    (node.getLeftNode().getValue() == true && 
112                                                    node.getRightNode().getValue() == false && 
113                                                    node.getLeftNode().getNodeMessage() != null))) {
114                            String logMessage = "test";
115                            
116                            if (node.getLeftNode().getValue() == true)
117                                    logMessage = node.getLeftNode().getNodeMessage();
118                            else if (node.getRightNode().getValue() == true)
119                                    logMessage = node.getRightNode().getNodeMessage();
120                            
121                            node.setNodeMessage(logMessage);
122                    }
123            }       
124            
125            /**
126             * Builds a success message for an OR node (b-tree node) where 
127             * left node and right node are true.
128             * 
129             * @param node
130             */
131            private void buildOr2NodeSuccessMessage(BooleanNode node) {
132                    // OR2
133                    if(node.getLabel().equals("+") &&
134                                    node.getLeftNode() != null && 
135                                    node.getRightNode() != null &&
136                                    node.getLeftNode().getValue() == true && 
137                                    node.getRightNode().getValue() == true && 
138                                    node.getLeftNode().getNodeMessage() != null && 
139                                    node.getRightNode().getNodeMessage() != null) {
140                    String logMessage = node.getLeftNode().getNodeMessage() + " " + 
141                            this.booleanOperators.getOrOperator() + " " + 
142                            node.getRightNode().getNodeMessage();
143    
144                            if(node.getParent() != null && 
145                                            ( (node.getLabel().equals("+") && 
146                                                            node.getParent().getLabel().equals("*")) || 
147                                                            (node.getLabel().equals("*") && 
148                                                                            node.getParent().getLabel().equals("+")))) {
149                                logMessage = "(" + logMessage + ")";
150                            }
151                            node.setNodeMessage(logMessage);
152                    } 
153            }       
154    }