Coverage Report - org.kuali.student.core.statement.naturallanguage.translators.StatementTranslator
 
Classes in this File Line Coverage Branch Coverage Complexity
StatementTranslator
82%
28/34
75%
6/8
2.429
 
 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.core.statement.naturallanguage.translators;
 17  
 
 18  
 import java.util.List;
 19  
 import java.util.Locale;
 20  
 
 21  
 import org.kuali.student.common.exceptions.DoesNotExistException;
 22  
 import org.kuali.student.common.exceptions.OperationFailedException;
 23  
 import org.kuali.student.common.messagebuilder.booleanmessage.BooleanMessage;
 24  
 import org.kuali.student.common.messagebuilder.booleanmessage.MessageContainer;
 25  
 import org.kuali.student.common.messagebuilder.booleanmessage.ast.BooleanMessageImpl;
 26  
 import org.kuali.student.core.statement.entity.Statement;
 27  
 import org.kuali.student.core.statement.naturallanguage.util.ReqComponentReference;
 28  
 import org.slf4j.Logger;
 29  
 import org.slf4j.LoggerFactory;
 30  
 
 31  
 /**
 32  
  * This class translates a LU (learning unit) statement into a specific 
 33  
  * natural language.  This class is not thread safe.
 34  
  */
 35  
 public class StatementTranslator {
 36  
     /** SLF4J logging framework */
 37  1
     final static Logger logger = LoggerFactory.getLogger(StatementTranslator.class);
 38  
 
 39  
     private String language;
 40  29
         private StatementParser statementParser = new StatementParser("*", "+");
 41  
         private ReqComponentTranslator reqComponentTranslator;
 42  
         private NaturalLanguageMessageBuilder messageBuilder;
 43  
 //    private ContextRegistry<Context<StatementAnchor>> contextRegistry;
 44  
 //    private TemplateTranslator templateTranslator = new TemplateTranslator();
 45  
     
 46  
         /**
 47  
          * Constructs a new natural language translator in the 
 48  
          * default language locale.
 49  
          */
 50  29
         public StatementTranslator() {
 51  29
                 this.language = Locale.getDefault().getLanguage();
 52  29
     }
 53  
 
 54  
         /**
 55  
          * Sets the translation language.
 56  
          * 
 57  
          * @param language Translation language
 58  
          */
 59  
         public void setLanguage(final String language) {
 60  31
                 this.language = language;
 61  31
         }
 62  
 
 63  
         /**
 64  
          * Sets the requirement component translator.
 65  
          * 
 66  
          * @param reqComponentTranslator Requirement component translator
 67  
          */
 68  
         public void setReqComponentTranslator(final ReqComponentTranslator reqComponentTranslator) {
 69  29
                 this.reqComponentTranslator = reqComponentTranslator;
 70  29
         }
 71  
 
 72  
         /**
 73  
          * Sets the message builder.
 74  
          * 
 75  
          * @param messageBuilder Message builder
 76  
          */
 77  
     public void setMessageBuilder(final NaturalLanguageMessageBuilder messageBuilder) {
 78  29
                 this.messageBuilder = messageBuilder;
 79  29
     }
 80  
 
 81  
         /**
 82  
          * Translates a statement in the default language for a specific natural 
 83  
          * language usuage type (context) into natural language.
 84  
          * This method is not thread safe.
 85  
          * 
 86  
          * @param statement Statement
 87  
          * @param nlUsageTypeKey Usuage type key (context)
 88  
          * @return Natural language statement translation
 89  
          * @throws DoesNotExistException CLU or statement id does not exists
 90  
          * @throws OperationFailedException Translation failed
 91  
          */
 92  
         public String translate(final Statement statement, final String nlUsageTypeKey) throws DoesNotExistException, OperationFailedException {
 93  18
                 return translate(statement, nlUsageTypeKey, this.language);
 94  
         }
 95  
         
 96  
         /**
 97  
          * Translates a statement for a specific natural language usuage 
 98  
          * type (context) into natural language.
 99  
          * This method is not thread safe.
 100  
          * 
 101  
          * @param language Language translation
 102  
          * @param statement Statement
 103  
          * @param nlUsageTypeKey Usuage type key (context)
 104  
          * @return Natural language statement translation
 105  
          * @throws DoesNotExistException CLU or statement id does not exists
 106  
          * @throws OperationFailedException Translation failed
 107  
          */
 108  
         public String translate(final Statement statement, final String nlUsageTypeKey, final String language) throws DoesNotExistException, OperationFailedException {
 109  19
                 if(statement == null) {
 110  1
                     throw new DoesNotExistException("Statement cannot be null");
 111  
                 }
 112  
 
 113  
                 try {
 114  18
                         String booleanExpression = this.statementParser.getBooleanExpressionAsReqComponents(statement);
 115  18
                         List<ReqComponentReference> reqComponentList = this.statementParser.getLeafReqComponents(statement);
 116  18
                         String message = "";
 117  18
                         if (booleanExpression != null && booleanExpression.length() > 0)
 118  18
                                 message = buildMessage(language, nlUsageTypeKey, booleanExpression, reqComponentList);
 119  
 //                String header = "";
 120  
 //                if(cluId != null && !cluId.isEmpty()) {
 121  
 //                        header = getHeader(statement, nlUsageTypeKey, cluId);
 122  
 //                }
 123  
 //                String header = getHeader(statement, nlUsageTypeKey);
 124  
 //                
 125  
 //                return header + message;
 126  18
                         return message;
 127  0
                 } catch (DoesNotExistException e) {
 128  0
                         logger.error(e.getMessage(), e);
 129  0
                         throw e;
 130  0
                 } catch (OperationFailedException e) {
 131  0
                         logger.error(e.getMessage(), e);
 132  0
                         throw e;
 133  
                 }
 134  
         }
 135  
 
 136  
         /**
 137  
          * Translates a statement directly attached to a CLU for a specific natural 
 138  
          * language usuage type (context) into natural language tree structure.
 139  
          * 
 140  
          * @param cluId Clu anchor
 141  
          * @param luStatement LU statement
 142  
          * @param nlUsageTypeKey Natural language usage type key (context)
 143  
          * @return Natural language root tree node
 144  
          * @throws DoesNotExistException CLU or statement does not exist
 145  
          * @throws OperationFailedException Translation failed
 146  
          */
 147  
 /*        public NLTranslationNodeInfo translateToTree(final String cluId, final CustomLuStatementInfo luStatement, final String nlUsageTypeKey) throws DoesNotExistException, OperationFailedException {
 148  
                 if(luStatement == null) {
 149  
 //                        return null;
 150  
                     throw new DoesNotExistException("LuStatement cannot be null");
 151  
                 }
 152  
 
 153  
                 String booleanExpression = statementParser.getBooleanExpressionAsReqComponents(luStatement);
 154  
                 String operator = (luStatement.getOperator() == null ? null : luStatement.getOperator().toString());
 155  
                 String booleanId = statementParser.getIdMap().get(luStatement.getId());
 156  
                 NLTranslationNodeInfo rootNode = new NLTranslationNodeInfo(luStatement.getId(), booleanId, operator);
 157  
                 rootNode.setBooleanExpression(booleanExpression);
 158  
 
 159  
                 createStatementTree(luStatement, rootNode, nlUsageTypeKey);
 160  
 
 161  
                 String translation = translate(cluId, luStatement, nlUsageTypeKey);
 162  
                 rootNode.setNLTranslation(translation);
 163  
 
 164  
                 return rootNode;
 165  
         }
 166  
         
 167  
         /**
 168  
          * Builds the full translated message.
 169  
          * 
 170  
          * @param nlUsageTypeKey Usuage type key
 171  
          * @param booleanExpression Boolean expression
 172  
          * @param reqComponentList Requirement component list
 173  
          * @return Translated message
 174  
          * @throws DoesNotExistException Requirement component does not exist
 175  
          * @throws OperationFailedException Translation failed
 176  
          */
 177  
         private String buildMessage(String language, String nlUsageTypeKey, String booleanExpression, List<ReqComponentReference> reqComponentList) throws DoesNotExistException, OperationFailedException {
 178  18
                 MessageContainer messageContainer = new MessageContainer();
 179  18
                 for(ReqComponentReference reqComponent : reqComponentList) {
 180  36
                         String translation = this.reqComponentTranslator.translate(reqComponent.getReqComponent(), nlUsageTypeKey, language);
 181  36
                         BooleanMessage bm = new BooleanMessageImpl(reqComponent.getBooleanId(), true, translation);
 182  36
                         messageContainer.addMessage(bm);
 183  36
                 }
 184  
                 
 185  18
                 String message = this.messageBuilder.buildMessage(language, booleanExpression, messageContainer);
 186  18
                 return message;
 187  
         }
 188  
         
 189  
         /**
 190  
          * Gets header for root <code>luStatement</code>.
 191  
          * 
 192  
          * @param statement LU statement
 193  
          * @param nlUsageTypeKey Natural language usuage type context key
 194  
          * @return Statement header
 195  
          * @throws DoesNotExistException CLU or header template does not exist
 196  
          */
 197  
         /*private String getHeader(Statement statement, String nlUsageTypeKey) throws OperationFailedException, DoesNotExistException {
 198  
         String template = getHeaderTemplate(statement, nlUsageTypeKey);
 199  
                 
 200  
         Map<String, Object> contextMap = buildContextMap(statement);
 201  
         String header = this.templateTranslator.translate(contextMap, template);
 202  
         
 203  
         return header;
 204  
         }*/
 205  
 
 206  
     /**
 207  
      * Builds a statement type context map.
 208  
      * 
 209  
          * @param statement Statement
 210  
          * @return Context map 
 211  
          * @throws DoesNotExistException
 212  
          */
 213  
         /*private Map<String, Object> buildContextMap(Statement statement) throws OperationFailedException, DoesNotExistException {
 214  
                 RefStatementRelation refStmtRel = statement.getRefStatementRelations().get(0);
 215  
                 if(refStmtRel == null) {
 216  
                 throw new DoesNotExistException("Reference statement relation not found for statement id: " + statement.getId());
 217  
                 }
 218  
 
 219  
                 StatementAnchor lua = new StatementAnchor(statement, refStmtRel.getRefObjectTypeKey(), refStmtRel.getRefObjectId());
 220  
 
 221  
                 String statementTypeKey = statement.getStatementType().getId();
 222  
                 Context<StatementAnchor> context = this.contextRegistry.get(statementTypeKey);
 223  
             if(context == null) {
 224  
                 throw new DoesNotExistException("Header context not found in registry for statement type key: " + statementTypeKey);
 225  
             }
 226  
                 Map<String, Object> contextMap = context.createContextMap(lua);
 227  
             
 228  
         return contextMap;
 229  
         }*/
 230  
 
 231  
         /**
 232  
          * Gets header template for root <code>statement</code>.
 233  
          * 
 234  
          * @param statement LU statement
 235  
          * @param nlUsageTypeKey Natural language usuage type context key
 236  
          * @return Header template
 237  
          * @throws DoesNotExistException Header template does not exist
 238  
          */
 239  
         /*private String getHeaderTemplate(Statement statement, String nlUsageTypeKey) throws DoesNotExistException {
 240  
                 for(StatementTypeHeaderTemplate header : statement.getStatementType().getStatementHeaders()) {
 241  
                         if(header.getNlUsageTypeKey().equals(nlUsageTypeKey) && header.getLanguage().equals(this.language)) {
 242  
                                 return (header.getTemplate() == null ? "" : header.getTemplate());
 243  
                         }
 244  
                 }
 245  
         throw new DoesNotExistException("Natural language usage type key '" + nlUsageTypeKey + "'" +
 246  
                         " and language code '" + this.language + "' for statement type header not found");
 247  
         }*/
 248  
 
 249  
         /**
 250  
          * Create a statement tree as <code>NLTranslationNodeInfo</code>.
 251  
          * 
 252  
          * @param luStatement LU statement
 253  
          * @param rootNode Root node to translate to
 254  
          * @param nlUsageTypeKey Natural language usuage type context key
 255  
          * @throws DoesNotExistException Requirement component does not exist
 256  
          * @throws OperationFailedException Translation failed
 257  
          */
 258  
 /*        private void createStatementTree(CustomLuStatementInfo luStatement, NLTranslationNodeInfo rootNode, String nlUsageTypeKey) 
 259  
                 throws DoesNotExistException, OperationFailedException {
 260  
                 if (luStatement.getChildren() == null || luStatement.getChildren().isEmpty()) {
 261  
                         List<NLTranslationNodeInfo> children = getReqComponents(luStatement.getRequiredComponents(), nlUsageTypeKey);
 262  
                         rootNode.setChildNodes(children);
 263  
                         rootNode.setNLTranslation(getNLTranslation(children, rootNode.getOperator()));
 264  
                         return;
 265  
                 }
 266  
 
 267  
                 for(Iterator<CustomLuStatementInfo> it = luStatement.getChildren().iterator(); it.hasNext();) {
 268  
                         CustomLuStatementInfo stmt = it.next();
 269  
                         String operator = (stmt.getOperator() == null ? null : stmt.getOperator().toString());
 270  
                         String booleanId = statementParser.getIdMap().get(stmt.getId());
 271  
                         NLTranslationNodeInfo node = new NLTranslationNodeInfo(stmt.getId(), booleanId, operator);
 272  
                         node.setParentNode(rootNode);
 273  
                         rootNode.addChildNode(node);
 274  
                         if (stmt.getChildren() == null || stmt.getChildren().isEmpty()) {
 275  
                                 List<NLTranslationNodeInfo> children = getReqComponents(stmt.getRequiredComponents(), nlUsageTypeKey);
 276  
                                 node.setChildNodes(children);
 277  
                                 node.setNLTranslation(getNLTranslation(children, node.getOperator()));
 278  
                         } else {
 279  
                                 createStatementTree(stmt, node, nlUsageTypeKey);
 280  
                         }
 281  
                 }
 282  
         }*/
 283  
         
 284  
         /**
 285  
          * Gets the node's natural language translation.
 286  
          * 
 287  
          * @param children Nodes children
 288  
          * @param operator Boolean operator
 289  
          * @return Node's natural language translation
 290  
          */
 291  
 /*        private String getNLTranslation(List<NLTranslationNodeInfo> children, String operator) {
 292  
                 StringBuilder sb = new StringBuilder();
 293  
                 for(Iterator<NLTranslationNodeInfo> it = children.iterator(); it.hasNext();) {
 294  
                         NLTranslationNodeInfo node = it.next();
 295  
                         sb.append(node.getNLTranslation());
 296  
                         if(it.hasNext()) {
 297  
                                 sb.append(" ");
 298  
                                 sb.append(operator.toLowerCase());
 299  
                                 sb.append(" ");
 300  
                         }
 301  
                 }
 302  
                 return sb.toString();
 303  
         }*/
 304  
 
 305  
         /**
 306  
          * Gets the requirement components as a list of translated nodes.
 307  
          * 
 308  
          * @param reqComponentList Requirement component list
 309  
          * @param nlUsageTypeKey Usuage type key (context)
 310  
          * @return List of translated nodes
 311  
          * @throws DoesNotExistException Requirement component does not exist
 312  
          * @throws OperationFailedException Translation fails
 313  
          */
 314  
 /*        private List<NLTranslationNodeInfo> getReqComponents(List<CustomReqComponentInfo> reqComponentList, String nlUsageTypeKey) 
 315  
                 throws DoesNotExistException, OperationFailedException {
 316  
                 List<NLTranslationNodeInfo> list = new ArrayList<NLTranslationNodeInfo>(reqComponentList.size());
 317  
                 for(CustomReqComponentInfo reqComp : reqComponentList) {
 318  
                         String translation = this.reqComponentTranslator.translate(reqComp, nlUsageTypeKey);
 319  
                         String booleanId = statementParser.getIdMap().get(reqComp.getId());
 320  
                         NLTranslationNodeInfo node = new NLTranslationNodeInfo(reqComp.getId(), booleanId, null);
 321  
                         node.setNLTranslation(translation);
 322  
                         list.add(node);
 323  
                 }
 324  
                 return list;
 325  
         }*/
 326  
 }