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 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 private static final TreeAdaptor adaptor = new CommonTreeAdaptor() {
49 public Object create(Token payload) {
50 return new BooleanNode(payload);
51 }
52 };
53
54
55
56
57 public BinaryMessageTree() {
58 language = Locale.getDefault().getLanguage();
59 nodes = new ArrayList<BooleanNode>();
60 }
61
62
63
64
65
66
67
68
69
70 public BinaryMessageTree(String language, Map<String, ? extends BooleanMessage> messageMap) {
71 this.language = language;
72 nodeMessageMap = messageMap;
73 nodes = new ArrayList<BooleanNode>();
74 }
75
76
77
78
79
80
81
82
83
84
85 public BooleanNode buildTree(String booleanFunction){
86 if (booleanFunction == null || booleanFunction.trim().isEmpty()) {
87 return null;
88 }
89
90 BooleanFunctionLexer lex = new BooleanFunctionLexer(new ANTLRStringStream(booleanFunction) );
91 CommonTokenStream tokens = new CommonTokenStream(lex);
92
93 BooleanFunctionParser parser = new BooleanFunctionParser(tokens);
94 parser.setTreeAdaptor(adaptor);
95
96
97 BooleanFunctionParser.booleanExpression_return booleanExpression = null;
98 try {
99 booleanExpression = parser.booleanExpression();
100 } catch (RecognitionException e) {
101 String parserErrorMsg = parser.getErrorMessage(e, parser.getTokenNames());
102 String errorMsg = "Boolean Function Parser Error. " +
103 "Invalid Boolean Expression: '" + booleanFunction + "'; " + parserErrorMsg;
104 throw new BooleanFunctionException(errorMsg, e);
105 }
106
107 return root = (BooleanNode) booleanExpression.getTree();
108 }
109
110
111
112
113
114
115
116
117
118 public void traverseTreePostOrder(BooleanNode bnode, BooleanNode parent) {
119 for (int i = 0; i < bnode.getChildCount(); i++) {
120 traverseTreePostOrder((BooleanNode) bnode.getChild(i), bnode);
121 }
122 setNode(bnode);
123 if (parent != null) {
124 bnode.setParent(parent);
125 }
126
127 if(logger.isDebugEnabled()) {
128 logger.debug(bnode.getText());
129 }
130 nodes.add(bnode);
131 }
132
133
134
135
136
137
138
139
140
141 public void traverseTreePostOrderDontSetNode(BooleanNode bnode, BooleanNode parent) {
142 if (bnode != null) {
143 for (int i = 0; i < bnode.getChildCount(); i++ ) {
144 traverseTreePostOrderDontSetNode((BooleanNode)bnode.getChild(i), bnode);
145 }
146
147 if (parent != null) {
148 bnode.setParent(parent);
149 }
150
151 if(logger.isDebugEnabled()) {
152 logger.debug(bnode.getText());
153 }
154 nodes.add(bnode);
155 }
156 }
157
158
159
160
161
162
163
164
165 private void setNode(BooleanNode bnode) {
166 bnode.setLanguage(language);
167
168 if (bnode.getChildCount() == 0) {
169
170 BooleanMessage message = nodeMessageMap.get(bnode.getLabel());
171 bnode.setValue(message.isSuccesful());
172 bnode.setNodeMessage(message.getMessage());
173 }
174 else {
175
176 BooleanNode child0 = (BooleanNode)bnode.getChild(0);
177 BooleanNode child1 = (BooleanNode)bnode.getChild(1);
178
179 if ( bnode.getLabel().equalsIgnoreCase("+") ) {
180
181 Boolean newValue = child0.getValue() || child1.getValue();
182 bnode.setValue(newValue);
183 bnode.setNodeMessage("null");
184 }
185 else if ( bnode.getLabel().equalsIgnoreCase("*") ) {
186
187 Boolean newValue = child0.getValue() && child1.getValue();
188 bnode.setValue(newValue);
189 bnode.setNodeMessage("null");
190 }
191 }
192 }
193
194
195
196
197
198
199 public List<BooleanNode> getAllNodes() {
200 return nodes;
201 }
202
203
204
205
206
207
208 public BooleanNode getRoot() {
209 return root;
210 }
211 }