1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
package org.kuali.student.common.messagebuilder.booleanmessage.ast; |
17 | |
|
18 | |
import java.util.ArrayList; |
19 | |
import java.util.List; |
20 | |
import java.util.Locale; |
21 | |
import java.util.Map; |
22 | |
|
23 | |
import org.antlr.runtime.ANTLRStringStream; |
24 | |
import org.antlr.runtime.CommonTokenStream; |
25 | |
import org.antlr.runtime.RecognitionException; |
26 | |
import org.antlr.runtime.Token; |
27 | |
import org.antlr.runtime.tree.CommonTreeAdaptor; |
28 | |
import org.antlr.runtime.tree.TreeAdaptor; |
29 | |
|
30 | |
import org.kuali.student.common.messagebuilder.booleanmessage.BooleanMessage; |
31 | |
import org.kuali.student.common.messagebuilder.booleanmessage.ast.exceptions.BooleanFunctionException; |
32 | |
import org.kuali.student.common.messagebuilder.booleanmessage.ast.parsers.BooleanFunctionLexer; |
33 | |
import org.kuali.student.common.messagebuilder.booleanmessage.ast.parsers.BooleanFunctionParser; |
34 | |
|
35 | |
import org.slf4j.Logger; |
36 | |
import org.slf4j.LoggerFactory; |
37 | |
|
38 | |
public class BinaryMessageTree { |
39 | |
|
40 | 1 | final static Logger logger = LoggerFactory.getLogger(BinaryMessageTree.class); |
41 | |
|
42 | |
private BooleanNode root; |
43 | |
private ArrayList<BooleanNode> nodes; |
44 | |
private String language; |
45 | |
|
46 | |
private Map<String, ? extends BooleanMessage> nodeMessageMap; |
47 | |
|
48 | 1 | private static final TreeAdaptor adaptor = new CommonTreeAdaptor() { |
49 | |
public Object create(Token payload) { |
50 | 720 | return new BooleanNode(payload); |
51 | |
} |
52 | |
}; |
53 | |
|
54 | |
|
55 | |
|
56 | |
|
57 | 24 | public BinaryMessageTree() { |
58 | 24 | language = Locale.getDefault().getLanguage(); |
59 | 24 | nodes = new ArrayList<BooleanNode>(); |
60 | 24 | } |
61 | |
|
62 | |
|
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
|
69 | |
|
70 | 22 | public BinaryMessageTree(String language, Map<String, ? extends BooleanMessage> messageMap) { |
71 | 22 | this.language = language; |
72 | 22 | nodeMessageMap = messageMap; |
73 | 22 | nodes = new ArrayList<BooleanNode>(); |
74 | 22 | } |
75 | |
|
76 | |
|
77 | |
|
78 | |
|
79 | |
|
80 | |
|
81 | |
|
82 | |
|
83 | |
|
84 | |
|
85 | |
public BooleanNode buildTree(String booleanFunction){ |
86 | 46 | if (booleanFunction == null || booleanFunction.trim().isEmpty()) { |
87 | 0 | return null; |
88 | |
} |
89 | |
|
90 | 46 | BooleanFunctionLexer lex = new BooleanFunctionLexer(new ANTLRStringStream(booleanFunction) ); |
91 | 46 | CommonTokenStream tokens = new CommonTokenStream(lex); |
92 | |
|
93 | 46 | BooleanFunctionParser parser = new BooleanFunctionParser(tokens); |
94 | 46 | parser.setTreeAdaptor(adaptor); |
95 | |
|
96 | |
|
97 | 46 | BooleanFunctionParser.booleanExpression_return booleanExpression = null; |
98 | |
try { |
99 | 46 | booleanExpression = parser.booleanExpression(); |
100 | 1 | } catch (RecognitionException e) { |
101 | 1 | String parserErrorMsg = parser.getErrorMessage(e, parser.getTokenNames()); |
102 | 1 | String errorMsg = "Boolean Function Parser Error. " + |
103 | |
"Invalid Boolean Expression: '" + booleanFunction + "'; " + parserErrorMsg; |
104 | 1 | throw new BooleanFunctionException(errorMsg, e); |
105 | 45 | } |
106 | |
|
107 | 45 | return root = (BooleanNode) booleanExpression.getTree(); |
108 | |
} |
109 | |
|
110 | |
|
111 | |
|
112 | |
|
113 | |
|
114 | |
|
115 | |
|
116 | |
|
117 | |
|
118 | |
public void traverseTreePostOrder(BooleanNode bnode, BooleanNode parent) { |
119 | 212 | for (int i = 0; i < bnode.getChildCount(); i++) { |
120 | 96 | traverseTreePostOrder((BooleanNode) bnode.getChild(i), bnode); |
121 | |
} |
122 | 116 | setNode(bnode); |
123 | 116 | if (parent != null) { |
124 | 96 | bnode.setParent(parent); |
125 | |
} |
126 | |
|
127 | 116 | if(logger.isDebugEnabled()) { |
128 | 0 | logger.debug(bnode.getText()); |
129 | |
} |
130 | 116 | nodes.add(bnode); |
131 | 116 | } |
132 | |
|
133 | |
|
134 | |
|
135 | |
|
136 | |
|
137 | |
|
138 | |
|
139 | |
|
140 | |
|
141 | |
public void traverseTreePostOrderDontSetNode(BooleanNode bnode, BooleanNode parent) { |
142 | 126 | if (bnode != null) { |
143 | 230 | for (int i = 0; i < bnode.getChildCount(); i++ ) { |
144 | 104 | traverseTreePostOrderDontSetNode((BooleanNode)bnode.getChild(i), bnode); |
145 | |
} |
146 | |
|
147 | 126 | if (parent != null) { |
148 | 104 | bnode.setParent(parent); |
149 | |
} |
150 | |
|
151 | 126 | if(logger.isDebugEnabled()) { |
152 | 0 | logger.debug(bnode.getText()); |
153 | |
} |
154 | 126 | nodes.add(bnode); |
155 | |
} |
156 | 126 | } |
157 | |
|
158 | |
|
159 | |
|
160 | |
|
161 | |
|
162 | |
|
163 | |
|
164 | |
|
165 | |
private void setNode(BooleanNode bnode) { |
166 | 116 | bnode.setLanguage(language); |
167 | |
|
168 | 116 | if (bnode.getChildCount() == 0) { |
169 | |
|
170 | 68 | BooleanMessage message = nodeMessageMap.get(bnode.getLabel()); |
171 | 68 | bnode.setValue(message.isSuccesful()); |
172 | 68 | bnode.setNodeMessage(message.getMessage()); |
173 | 68 | } |
174 | |
else { |
175 | |
|
176 | 48 | BooleanNode child0 = (BooleanNode)bnode.getChild(0); |
177 | 48 | BooleanNode child1 = (BooleanNode)bnode.getChild(1); |
178 | |
|
179 | 48 | if ( bnode.getLabel().equalsIgnoreCase("+") ) { |
180 | |
|
181 | 20 | Boolean newValue = child0.getValue() || child1.getValue(); |
182 | 20 | bnode.setValue(newValue); |
183 | 20 | bnode.setNodeMessage("null"); |
184 | 20 | } |
185 | 28 | else if ( bnode.getLabel().equalsIgnoreCase("*") ) { |
186 | |
|
187 | 28 | Boolean newValue = child0.getValue() && child1.getValue(); |
188 | 28 | bnode.setValue(newValue); |
189 | 28 | bnode.setNodeMessage("null"); |
190 | |
} |
191 | |
} |
192 | 116 | } |
193 | |
|
194 | |
|
195 | |
|
196 | |
|
197 | |
|
198 | |
|
199 | |
public List<BooleanNode> getAllNodes() { |
200 | 42 | return nodes; |
201 | |
} |
202 | |
|
203 | |
|
204 | |
|
205 | |
|
206 | |
|
207 | |
|
208 | |
public BooleanNode getRoot() { |
209 | 39 | return root; |
210 | |
} |
211 | |
} |