Coverage Report - org.kuali.student.core.statement.ui.client.widgets.rules.RuleExpressionEditor
 
Classes in this File Line Coverage Branch Coverage Complexity
RuleExpressionEditor
0%
0/102
0%
0/16
2.714
RuleExpressionEditor$1
0%
0/11
0%
0/4
2.714
RuleExpressionEditor$2
0%
0/5
0%
0/8
2.714
RuleExpressionEditor$3
0%
0/23
0%
0/10
2.714
RuleExpressionEditor$4
0%
0/9
0%
0/2
2.714
 
 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.ui.client.widgets.rules;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.List;
 20  
 
 21  
 import org.kuali.student.common.ui.client.mvc.Callback;
 22  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 23  
 import org.kuali.student.common.ui.client.widgets.KSLabel;
 24  
 import org.kuali.student.common.ui.client.widgets.KSTextArea;
 25  
 import org.kuali.student.core.statement.dto.ReqComponentInfo;
 26  
 
 27  
 import com.google.gwt.event.dom.client.ClickEvent;
 28  
 import com.google.gwt.event.dom.client.ClickHandler;
 29  
 import com.google.gwt.event.dom.client.KeyUpEvent;
 30  
 import com.google.gwt.event.dom.client.KeyUpHandler;
 31  
 import com.google.gwt.user.client.ui.*;
 32  
 
 33  0
 public class RuleExpressionEditor extends FlowPanel {
 34  
 
 35  
     //view's widgets
 36  0
     private KSTextArea expressionTextBox = new KSTextArea();
 37  0
     private HTML htmlErrorMessage = new HTML();    
 38  0
     private KSButton btnUpdate = new KSButton("Update");
 39  0
     private KSButton btnUndo = new KSButton("Undo");
 40  0
     private FlowPanel ruleTablePanel = new FlowPanel();
 41  0
     private KSLabel noRuleText = new KSLabel("");
 42  0
     private Panel pnlMissingExpressions = new VerticalPanel();
 43  
 
 44  
     //rule table
 45  0
     private RuleTable  ruleTable = new RuleTable(false);
 46  0
     private ClickHandler ruleTableEditClauseHandler = null;
 47  
 
 48  
     //view's data
 49  
     private RuleInfo rule;
 50  
     private String previewExpression;
 51  
     private Callback reqCompEditCallback;
 52  
     private Callback ruleChangedCallback;
 53  
     private RuleManageWidget parent;
 54  0
     private boolean ruleChanged = false;
 55  
 
 56  
     // helper object
 57  0
     private RuleExpressionParser ruleExpressionParser = new RuleExpressionParser();
 58  
        
 59  0
     public RuleExpressionEditor(RuleManageWidget parent) {
 60  0
         this.parent = parent;
 61  
 
 62  0
         FlowPanel expressionBox = new FlowPanel();
 63  0
         HorizontalPanel expressionAndMsg = new HorizontalPanel();
 64  0
         expressionBox.setStyleName("KS-Program-Rule-LogicView-ExpressionPanel");
 65  0
         expressionTextBox.ensureDebugId("Expression Text Area");
 66  0
         expressionTextBox.addStyleName("KS-Program-Rule-LogicView-ExpressionText");
 67  0
         expressionAndMsg.add(expressionTextBox);
 68  0
         expressionAndMsg.add(htmlErrorMessage);
 69  0
         expressionBox.add(expressionAndMsg);
 70  0
         btnUpdate.addStyleName("KS-Program-Rule-LogicView-Update-Button");
 71  0
         FlowPanel buttonsPanel = new FlowPanel();
 72  0
         buttonsPanel.add(btnUpdate);
 73  0
         btnUndo.addStyleName("KS-Program-Rule-LogicView-Undo-Button");
 74  0
         buttonsPanel.add(btnUndo);
 75  0
         buttonsPanel.addStyleName("KS-Program-Rule-LogicView-ButtonPanel");
 76  0
         expressionBox.add(buttonsPanel);
 77  0
         add(expressionBox);
 78  
 
 79  0
         ruleTablePanel.setStyleName("KS-Program-Rule-LogicView-RulePanel");
 80  0
         ruleTablePanel.add(ruleTable);
 81  0
         ruleTablePanel.add(noRuleText);
 82  0
         ruleTablePanel.add(pnlMissingExpressions);
 83  0
         add(ruleTablePanel);
 84  
 
 85  0
         previewExpression = "";
 86  
 
 87  0
         setupHandlers();
 88  0
     }
 89  
 
 90  
     public void setRule(RuleInfo rule) {
 91  0
         this.rule = rule;
 92  0
         redraw();
 93  0
     }
 94  
 
 95  
     private void setupHandlers() {
 96  0
         ruleTableEditClauseHandler = new ClickHandler() {
 97  
             @Override
 98  
             public void onClick(ClickEvent event) {
 99  0
                 HTMLTable.Cell cell = ruleTable.getCellForEvent(event);
 100  0
                 if (cell == null) {
 101  0
                     return;
 102  
                 }
 103  
 
 104  0
                 RuleNodeWidget widget = (RuleNodeWidget) ruleTable.getWidget(cell.getRowIndex(), cell.getCellIndex());
 105  0
                 Object userObject = widget.getNode().getUserObject();
 106  0
                 if (userObject instanceof ReqComponentVO) {
 107  0
                     widget.setEditMode(true);
 108  0
                     final ReqComponentVO tempRule = (ReqComponentVO) userObject;
 109  0
                     reqCompEditCallback.exec(tempRule.getReqComponentInfo());
 110  
                 }
 111  0
             }
 112  
         };                        
 113  0
         expressionTextBox.addKeyUpHandler(new KeyUpHandler() {
 114  
             public void onKeyUp(KeyUpEvent event) {
 115  
                 // escape error keys
 116  0
                 if(event.getNativeKeyCode() == 37 
 117  
                         ||event.getNativeKeyCode() == 38
 118  
                         ||event.getNativeKeyCode() == 39
 119  
                         ||event.getNativeKeyCode() == 40){
 120  0
                         return;
 121  
                 }
 122  0
                 btnUpdate.setEnabled(true);
 123  0
             }
 124  
         });
 125  0
         btnUpdate.addClickHandler(new ClickHandler() {
 126  
             public void onClick(ClickEvent event) {
 127  
 
 128  
                 //get and format logic expression of the rule
 129  0
                 previewExpression = expressionTextBox.getText();
 130  0
                 previewExpression = previewExpression.replaceAll("\n", " ");
 131  0
                 previewExpression = previewExpression.replaceAll("\r", " ");
 132  0
                 ruleExpressionParser.setExpression(previewExpression);
 133  
 
 134  
                 //validate the expression
 135  0
                 List<ReqComponentVO> rcs = (rule.getStatementVO() == null || rule.getStatementVO().getAllReqComponentVOs() == null) ?
 136  
                                                 new ArrayList<ReqComponentVO>() : rule.getStatementVO().getAllReqComponentVOs();
 137  0
                 List<String> errorMessages = new ArrayList<String>();
 138  0
                 boolean validExpression = ruleExpressionParser.validateExpression(errorMessages, rcs);
 139  
 
 140  
                 //show errors and don't change anything else
 141  0
                 if (!validExpression) {
 142  
 
 143  
                     //show missing 'subrules' that were removed from the expression box by the user
 144  0
                     List<ReqComponentVO> missingRCs = new ArrayList<ReqComponentVO>();
 145  0
                     rcs = (rule.getStatementVO() == null || rule.getStatementVO().getAllReqComponentVOs() == null) ?
 146  
                                                     new ArrayList<ReqComponentVO>() : rule.getStatementVO().getAllReqComponentVOs();
 147  0
                     ruleExpressionParser.checkMissingRCs(missingRCs, rcs);
 148  0
                     showMissingRCs(missingRCs);
 149  
 
 150  0
                     showErrors(errorMessages);
 151  0
                     return;
 152  
                 }
 153  
 
 154  
                 //update the rule based on the updated logic expression
 155  0
                 StatementVO newStatementVO = ruleExpressionParser.parseExpressionIntoStatementVO(previewExpression, rule.getStatementVO(), rule.getStatementTypeKey());
 156  0
                 rule.setStatementVO(newStatementVO);
 157  0
                 rule.getEditHistory().save(newStatementVO);
 158  
 
 159  
                 //display rule table for updated rule
 160  0
                 redraw();
 161  
 
 162  0
                 parent.updateObjectRule(rule);
 163  0
                 ruleChanged = true;
 164  0
                 ruleChangedCallback.exec(true);
 165  0
             }
 166  
         });
 167  
         
 168  0
         btnUndo.addClickHandler(new ClickHandler() {
 169  
             public void onClick(ClickEvent event) {
 170  0
                 StatementVO previousState = rule.getEditHistory().undo();
 171  0
                 if (previousState != null) {
 172  0
                     rule.setStatementVO(previousState);
 173  
                 }
 174  0
                 redraw();
 175  0
                 parent.updateObjectRule(rule);
 176  0
                 ruleChanged = true;
 177  0
                 ruleChangedCallback.exec(true);
 178  0
             }
 179  
         });
 180  0
     }
 181  
 
 182  
     private void redraw() {
 183  0
         htmlErrorMessage.setHTML("");
 184  0
         ruleTable.clear();
 185  0
         noRuleText.setText("");
 186  0
         ruleChanged = false;
 187  0
         setEnabledView(true);
 188  0
         expressionTextBox.setText(rule.getExpression().trim().isEmpty() ? "" : rule.getExpression().trim());        
 189  
 
 190  0
         if (rule.getExpression().trim().isEmpty()) {
 191  0
             noRuleText.setText("No rules have been added");
 192  0
             btnUpdate.setEnabled(false);
 193  0
             return;
 194  
         }
 195  
 
 196  0
         btnUpdate.setEnabled(false);    //redraw rule means no outstanding change to the expression    
 197  0
         ruleTable.buildTable(rule.getStatementTree());
 198  0
         ruleTable.addEditClauseHandler(ruleTableEditClauseHandler);
 199  0
     }
 200  
 
 201  
     private void showMissingRCs(List<ReqComponentVO> missingRCs) {
 202  0
         VerticalPanel pnlRCList = new VerticalPanel();
 203  0
         boolean missingExprFound = false;       
 204  0
         pnlMissingExpressions.clear();
 205  
 
 206  0
         for (ReqComponentVO rc : missingRCs) {
 207  0
             HorizontalPanel pnlRcListRow = new HorizontalPanel();
 208  0
             if (rc.getGuiReferenceLabelId() != null) {
 209  0
                 KSLabel rcLabel = new KSLabel(rc.getGuiReferenceLabelId());
 210  0
                 rcLabel.setStyleName("KS-Program-Rule-LogicView-Rule-ID");
 211  0
                 pnlRcListRow.add(rcLabel);
 212  0
                 missingExprFound = true;
 213  
             }
 214  0
             pnlRCList.add(pnlRcListRow);
 215  0
         }
 216  
         
 217  0
         if (missingExprFound) {
 218  0
             KSLabel missingExprTitle = new KSLabel("The following rules do not exist");
 219  0
             missingExprTitle.setStyleName("KS-Program-Rule-LogicView-Missing-Rules");
 220  0
             pnlMissingExpressions.add(missingExprTitle);                        
 221  0
             pnlMissingExpressions.add(pnlRCList);
 222  
         }        
 223  0
     }
 224  
     
 225  
     private void showErrors(List<String> errorMessages) {
 226  0
         StringBuilder sb = new StringBuilder("");
 227  0
         boolean firstRow = true;
 228  0
         for (String errorMessage : errorMessages) {
 229  0
             if (!firstRow) {
 230  0
                 sb.append(",<BR>");
 231  
             }
 232  0
             firstRow = false;
 233  0
             sb.append(errorMessage);
 234  
         }
 235  0
         htmlErrorMessage.getElement().getStyle().setProperty("color", "red");
 236  0
         htmlErrorMessage.setHTML(sb.toString());
 237  0
     }
 238  
 
 239  
     private void setEnableButtons(boolean enabled) {
 240  0
         if (enabled) {
 241  0
             btnUpdate.setEnabled(enabled);
 242  0
             btnUndo.setEnabled(rule.getEditHistory().isUndoable()); 
 243  
         } else {
 244  0
             btnUpdate.setEnabled(false);
 245  0
             btnUndo.setEnabled(false);
 246  
         }
 247  0
     }
 248  
 
 249  
     public void setEnabledView(boolean enabled) {
 250  0
         setEnableButtons(enabled);
 251  0
         ruleTable.setEnabled(enabled);
 252  0
         expressionTextBox.setEnabled(enabled);
 253  0
     }
 254  
 
 255  
     public void addReqCompEditButtonClickCallback(Callback<ReqComponentInfo> callback) {
 256  0
         reqCompEditCallback = callback;
 257  0
     }
 258  
 
 259  
     public void addRuleChangedButtonClickCallback(Callback<Boolean> callback) {
 260  0
         ruleChangedCallback = callback;
 261  0
     }
 262  
 }