|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AbstractMessageBuilder | Line # 40 | 44 | 0% | 19 | 9 | 85.5% |
0.8548387
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (38) | |||
| Result | |||
|
0.6935484
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage6
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage6
|
1 PASS | |
|
0.67741936
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage11
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage11
|
1 PASS | |
|
0.67741936
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessageTemplate4_False
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessageTemplate4_False
|
1 PASS | |
|
0.67741936
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessageTemplate2_NullContextMap_False
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessageTemplate2_NullContextMap_False
|
1 PASS | |
|
0.67741936
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage5_True
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage5_True
|
1 PASS | |
|
0.67741936
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessageTemplate3_True
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessageTemplate3_True
|
1 PASS | |
|
0.67741936
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessageTemplate1_NullContextMap_True
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessageTemplate1_NullContextMap_True
|
1 PASS | |
|
0.66129035
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage8
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage8
|
1 PASS | |
|
0.66129035
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage1_True
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage1_True
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageTranslatorTest.testTranslateStatement_English
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageTranslatorTest.testTranslateStatement_English
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement1_English_EmptyCluId
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement1_English_EmptyCluId
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageTranslatorTest.testTranslateStatement_EnglishGerman
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageTranslatorTest.testTranslateStatement_EnglishGerman
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement1_EnglishGerman
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement1_EnglishGerman
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageTranslatorTest.testTranslateStatement_German
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageTranslatorTest.testTranslateStatement_German
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement3
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement3
|
1 PASS | |
|
0.66129035
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage3_False
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage3_False
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement5
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement5
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement2
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement2
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement1_English_NullCluId
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement1_English_NullCluId
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageMessageBuilderTest.testConstructor1_BuildMessage_Success
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageMessageBuilderTest.testConstructor1_BuildMessage_Success
|
1 PASS | |
|
0.66129035
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage10
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage10
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageMessageBuilderTest.testConstructor2_BuildMessage_Success
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageMessageBuilderTest.testConstructor2_BuildMessage_Success
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.service.impl.TestStatementServiceImpl.testGetNaturalLanguageForRefStatementRelation
org.kuali.student.core.statement.service.impl.TestStatementServiceImpl.testGetNaturalLanguageForRefStatementRelation
|
1 PASS | |
|
0.66129035
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage2_True
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage2_True
|
1 PASS | |
|
0.66129035
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage12
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage12
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement6
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement6
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatementId1
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatementId1
|
1 PASS | |
|
0.66129035
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage4_False
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage4_False
|
1 PASS | |
|
0.66129035
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage9
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage9
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement1_English
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement1_English
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageMessageBuilderTest.testConstructor3_BuildMessage_Success
org.kuali.student.core.statement.naturallanguage.translators.NaturalLanguageMessageBuilderTest.testConstructor3_BuildMessage_Success
|
1 PASS | |
|
0.66129035
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage7
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage7
|
1 PASS | |
|
0.66129035
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage13
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage13
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement4
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement4
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement1_German
org.kuali.student.core.statement.naturallanguage.translators.StatementTranslatorTest.testTranslateStatement1_German
|
1 PASS | |
|
0.66129035
|
org.kuali.student.core.statement.service.impl.TestStatementServiceImpl.testGetNaturalLanguageForStatement
org.kuali.student.core.statement.service.impl.TestStatementServiceImpl.testGetNaturalLanguageForStatement
|
1 PASS | |
|
0.516129
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessageTemplate5_False_Exception
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessageTemplate5_False_Exception
|
1 PASS | |
|
0.22580644
|
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage1_InvalidBooleanExpression
org.kuali.student.common.messagebuilder.impl.MessageBuilderImplTest.testBuildMessage1_InvalidBooleanExpression
|
1 PASS | |
| 1 | /** | |
| 2 | * Copyright 2010 The Kuali Foundation Licensed under the | |
| 3 | * Educational Community License, Version 2.0 (the "License"); you may | |
| 4 | * not use this file except in compliance with the License. You may | |
| 5 | * obtain a copy of the License at | |
| 6 | * | |
| 7 | * http://www.osedu.org/licenses/ECL-2.0 | |
| 8 | * | |
| 9 | * Unless required by applicable law or agreed to in writing, | |
| 10 | * software distributed under the License is distributed on an "AS IS" | |
| 11 | * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | |
| 12 | * or implied. See the License for the specific language governing | |
| 13 | * permissions and limitations under the License. | |
| 14 | */ | |
| 15 | ||
| 16 | package org.kuali.student.common.messagebuilder.impl; | |
| 17 | ||
| 18 | import java.util.HashMap; | |
| 19 | import java.util.List; | |
| 20 | import java.util.Map; | |
| 21 | ||
| 22 | import org.apache.velocity.exception.VelocityException; | |
| 23 | import org.kuali.student.common.messagebuilder.MessageTreeBuilder; | |
| 24 | import org.kuali.student.common.messagebuilder.booleanmessage.BooleanMessage; | |
| 25 | import org.kuali.student.common.messagebuilder.booleanmessage.ast.BinaryMessageTree; | |
| 26 | import org.kuali.student.common.messagebuilder.booleanmessage.ast.BooleanFunction; | |
| 27 | import org.kuali.student.common.messagebuilder.booleanmessage.ast.BooleanFunctionResult; | |
| 28 | import org.kuali.student.common.messagebuilder.booleanmessage.ast.BooleanMessageImpl; | |
| 29 | import org.kuali.student.common.messagebuilder.booleanmessage.ast.BooleanNode; | |
| 30 | import org.kuali.student.common.messagebuilder.booleanmessage.ast.exceptions.BooleanFunctionException; | |
| 31 | import org.kuali.student.common.messagebuilder.impl.exceptions.MessageBuilderException; | |
| 32 | import org.kuali.student.common.util.VelocityTemplateEngine; | |
| 33 | ||
| 34 | /** | |
| 35 | * This <code>AbstractMessageBuilder</code> class builds a summary message | |
| 36 | * from plain strings or Velocity template messages. Summary message is built | |
| 37 | * from analysing the outcome of a boolean expression. | |
| 38 | * If no language is specified then the default language locale is used. | |
| 39 | */ | |
| 40 | public abstract class AbstractMessageBuilder { | |
| 41 | private final VelocityTemplateEngine templateEngine = new VelocityTemplateEngine(); | |
| 42 | ||
| 43 | private String booleanExpression; | |
| 44 | private Map<String, ? extends BooleanMessage> messageMap; | |
| 45 | private Map<String, Object> messageContextMap; | |
| 46 | private String language; | |
| 47 | private MessageTreeBuilder treeNodeMessageBuilder; | |
| 48 | ||
| 49 | /** | |
| 50 | * Constructor. | |
| 51 | * | |
| 52 | * @param language Language | |
| 53 | * @param treeNodeMessageBuilder AST tree node Message builder | |
| 54 | */ | |
| 55 | 30 |
public AbstractMessageBuilder(final String language, final MessageTreeBuilder treeNodeMessageBuilder) { |
| 56 | 30 | this.language = language; |
| 57 | 30 | this.treeNodeMessageBuilder = treeNodeMessageBuilder; |
| 58 | } | |
| 59 | ||
| 60 | /** | |
| 61 | * <p>Builds and evaluates a boolean expression and returns the message and result | |
| 62 | * of the expression. Messages in the <code>messageMap</code> can | |
| 63 | * also contain VTL (Velocity Template Language) but without any VTL keys</p> | |
| 64 | * <p><b>Note:</b> Order of boolean operation: ANDs before ORs and operations | |
| 65 | * inside parentheses before anything else.</p> | |
| 66 | * Example 1: 'A AND B OR C AND D' internally evaluates to '(A AND B) OR (C AND D)' | |
| 67 | * <pre><code>booleanExpression</code> = "A*B+C*D"</pre> | |
| 68 | * Example 2: '(M1 AND M2) OR M3' | |
| 69 | * <pre><code>booleanExpression</code> = "(M1*M2)+M3"</pre> | |
| 70 | * | |
| 71 | * @param booleanExpression Boolean expression | |
| 72 | * @param messageMap Contains a map of messages (or VTL) | |
| 73 | * @return Boolean function result | |
| 74 | */ | |
| 75 | 39 |
public BooleanFunctionResult build( |
| 76 | final String booleanExpression, | |
| 77 | final Map<String, ? extends BooleanMessage> messageMap) { | |
| 78 | 39 | this.booleanExpression = booleanExpression; |
| 79 | 39 | this.messageMap = messageMap; |
| 80 | ||
| 81 | 39 | return build(); |
| 82 | } | |
| 83 | ||
| 84 | /** | |
| 85 | * <p>Builds and evaluates a boolean expression and returns the message and result | |
| 86 | * of the expression. Messages in the <code>messageMap</code> can | |
| 87 | * also contain VTL (Velocity Template Language). | |
| 88 | * <code>messageContextMap</code> contains Velocity key/value entries | |
| 89 | * referenced in the <code>messageMap</code>.</p> | |
| 90 | * <p><b>Note:</b> Order of boolean operation: ANDs before ORs and operations | |
| 91 | * inside parentheses before anything else.</p> | |
| 92 | * Example 1: 'A AND B OR C AND D' internally evaluates to '(A AND B) OR (C AND D)' | |
| 93 | * <pre><code>booleanExpression</code> = "A*B+C*D"</pre> | |
| 94 | * Example 2: '(M1 AND M2) OR M3' | |
| 95 | * <pre><code>booleanExpression</code> = "(M1*M2)+M3"</pre> | |
| 96 | * | |
| 97 | * | |
| 98 | * @param booleanExpression Boolean expression | |
| 99 | * @param messageMap Contains a map of messages (or VTL) | |
| 100 | * @param messageContextMap Message contact map for Velocity Template Engine | |
| 101 | * @return Boolean function result | |
| 102 | * @throws MessageBuilderException Errors building message | |
| 103 | */ | |
| 104 | 5 |
public BooleanFunctionResult build( |
| 105 | final String booleanExpression, | |
| 106 | final Map<String, ? extends BooleanMessage> messageMap, | |
| 107 | final Map<String, Object> messageContextMap) { | |
| 108 | 5 | this.booleanExpression = booleanExpression; |
| 109 | 5 | this.messageMap = messageMap; |
| 110 | 5 | this.messageContextMap = messageContextMap; |
| 111 | ||
| 112 | 5 | return build(); |
| 113 | } | |
| 114 | ||
| 115 | 44 |
public BooleanFunctionResult build() { |
| 116 | 44 | BinaryMessageTree astTree = null; |
| 117 | ||
| 118 | 44 | try { |
| 119 | // set the functionString and Maps from the proposition container | |
| 120 | 44 | Map<String, BooleanMessage> nodeMessageMap = buildMessageMap(); |
| 121 | ||
| 122 | // go parse function in buildTree | |
| 123 | 42 | astTree = new BinaryMessageTree(this.language, nodeMessageMap); |
| 124 | 42 | BooleanNode root = astTree.buildTree(this.booleanExpression); |
| 125 | 42 | astTree.traverseTreePostOrder(root, null); |
| 126 | ||
| 127 | 42 | List<BooleanNode> treeNodes = astTree.getAllNodes(); |
| 128 | // tree node order in the list is important for building | |
| 129 | // the success and failure message | |
| 130 | 42 | this.treeNodeMessageBuilder.buildMessage(treeNodes); |
| 131 | } catch(VelocityException e) { | |
| 132 | 1 | throw new MessageBuilderException("Building Velocity message failed: " + e.getMessage(), e); |
| 133 | } catch (BooleanFunctionException e) { | |
| 134 | 1 | throw new MessageBuilderException("Building message failed: " + e.getMessage(), e); |
| 135 | } | |
| 136 | ||
| 137 | // This is the final rule report message summary | |
| 138 | 42 | String message = astTree.getRoot().getNodeMessage(); |
| 139 | 42 | Boolean result = astTree.getRoot().getValue(); |
| 140 | ||
| 141 | // Removed starting and ending brackets if they are the only brackets in the message | |
| 142 | 42 | if (message.startsWith("(") && message.endsWith(")") && |
| 143 | message.replaceAll("[^(]","").length() == 1 && | |
| 144 | message.replaceAll("[^)]","").length() == 1) { | |
| 145 | 4 | message = message.substring(1, message.length()-1); |
| 146 | } | |
| 147 | ||
| 148 | 42 | return new BooleanFunctionResult(this.booleanExpression, result, message); |
| 149 | } | |
| 150 | ||
| 151 | /** | |
| 152 | * Builds message map. Also builds message map using velocity templates. | |
| 153 | * | |
| 154 | * @return Boolean message map | |
| 155 | */ | |
| 156 | 44 |
private Map<String, BooleanMessage> buildMessageMap() { |
| 157 | 44 | Map<String, BooleanMessage> nodeMessageMap = new HashMap<String, BooleanMessage>(); |
| 158 | ||
| 159 | 44 | if (this.booleanExpression == null || this.booleanExpression.isEmpty()) { |
| 160 | 0 | throw new MessageBuilderException("Boolean expression is null"); |
| 161 | } | |
| 162 | ||
| 163 | 44 | BooleanFunction func = new BooleanFunction(this.booleanExpression); |
| 164 | 43 | List<String> funcVars = func.getVariables(); |
| 165 | ||
| 166 | 43 | if(funcVars == null || funcVars.isEmpty()) { |
| 167 | 0 | throw new MessageBuilderException("Boolean function variables are null or empty. Boolean expression: " + this.booleanExpression); |
| 168 | } | |
| 169 | ||
| 170 | 43 | for (String id : funcVars) { |
| 171 | 114 | if(id == null) { |
| 172 | 0 | throw new MessageBuilderException("Boolean variable id is null or empty. Boolean variable ids: " + funcVars); |
| 173 | } | |
| 174 | ||
| 175 | 114 | BooleanMessage message = this.messageMap.get(id); |
| 176 | ||
| 177 | 114 | if (message == null) { |
| 178 | 0 | throw new MessageBuilderException("Boolean message is null for id='" + id + "'"); |
| 179 | } | |
| 180 | ||
| 181 | 114 | BooleanMessage booleanMessage = buildMessage(message); |
| 182 | 113 | nodeMessageMap.put(id, booleanMessage); |
| 183 | } | |
| 184 | ||
| 185 | 42 | return nodeMessageMap; |
| 186 | } | |
| 187 | ||
| 188 | /** | |
| 189 | * Builds a failure/success message using the Velocity template engine. | |
| 190 | * | |
| 191 | * @param message Boolean failure/success message | |
| 192 | * @return | |
| 193 | */ | |
| 194 | 114 |
private BooleanMessage buildMessage(BooleanMessage message) { |
| 195 | 114 | String msg = message.getMessage(); |
| 196 | ||
| 197 | 114 | if(msg != null) { |
| 198 | 114 | msg = this.templateEngine.evaluate(this.messageContextMap, msg); |
| 199 | } | |
| 200 | ||
| 201 | 113 | return new BooleanMessageImpl(message.getMessageId(), message.isSuccesful(), msg); |
| 202 | } | |
| 203 | } | |
|
||||||||||||