Coverage Report - org.kuali.student.common.ui.client.configurable.mvc.LayoutController
 
Classes in this File Line Coverage Branch Coverage Complexity
LayoutController
0%
0/139
0%
0/78
1.959
LayoutController$1
0%
0/3
N/A
1.959
LayoutController$1$1
0%
0/6
N/A
1.959
LayoutController$2
0%
0/9
0%
0/4
1.959
LayoutController$2$1
0%
0/5
N/A
1.959
LayoutController$2$2
0%
0/5
N/A
1.959
LayoutController$3
0%
0/10
0%
0/10
1.959
LayoutController$4
0%
0/3
N/A
1.959
LayoutController$5
0%
0/6
N/A
1.959
LayoutController$5$1
0%
0/3
N/A
1.959
LayoutController$6
0%
0/3
N/A
1.959
LayoutController$7
0%
0/5
0%
0/2
1.959
 
 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.ui.client.configurable.mvc;
 17  
 
 18  
 import java.util.HashMap;
 19  
 import java.util.LinkedHashMap;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 import java.util.Map.Entry;
 23  
 
 24  
 import org.kuali.student.common.ui.client.configurable.mvc.layouts.ViewLayoutController;
 25  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
 26  
 import org.kuali.student.common.ui.client.configurable.mvc.views.SectionView;
 27  
 import org.kuali.student.common.ui.client.event.ActionEvent;
 28  
 import org.kuali.student.common.ui.client.event.SaveActionEvent;
 29  
 import org.kuali.student.common.ui.client.event.SectionUpdateEvent;
 30  
 import org.kuali.student.common.ui.client.event.SectionUpdateHandler;
 31  
 import org.kuali.student.common.ui.client.event.ValidateRequestEvent;
 32  
 import org.kuali.student.common.ui.client.event.ValidateRequestHandler;
 33  
 import org.kuali.student.common.ui.client.mvc.ActionCompleteCallback;
 34  
 import org.kuali.student.common.ui.client.mvc.Callback;
 35  
 import org.kuali.student.common.ui.client.mvc.Controller;
 36  
 import org.kuali.student.common.ui.client.mvc.DataModel;
 37  
 import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
 38  
 import org.kuali.student.common.ui.client.mvc.View;
 39  
 import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
 40  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 41  
 import org.kuali.student.common.ui.client.widgets.KSLightBox;
 42  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.FieldElement;
 43  
 import org.kuali.student.core.validation.dto.ValidationResultInfo;
 44  
 import org.kuali.student.core.validation.dto.ValidationResultInfo.ErrorLevel;
 45  
 
 46  
 import com.google.gwt.core.client.GWT;
 47  
 import com.google.gwt.event.dom.client.ClickEvent;
 48  
 import com.google.gwt.event.dom.client.ClickHandler;
 49  
 import com.google.gwt.user.client.ui.FlowPanel;
 50  
 import com.google.gwt.user.client.ui.Widget;
 51  
 
 52  0
 public abstract class LayoutController extends Controller implements ViewLayoutController, View {
 53  
 
 54  0
         protected Map<Enum<?>, View> viewMap = new LinkedHashMap<Enum<?>, View>();
 55  0
         protected Map<String, Enum<?>> viewEnumMap = new HashMap<String, Enum<?>>();
 56  
         protected Enum<?> defaultView;
 57  
         
 58  
         protected String name;
 59  
         protected Enum<?> viewType;
 60  
 
 61  
     protected View startPopupView;
 62  
     protected KSLightBox startViewWindow;
 63  
         
 64  
     public LayoutController(String controllerId){
 65  0
         super(controllerId);
 66  
         //Global section update Event handling
 67  0
                 addApplicationEventHandler(SectionUpdateEvent.TYPE, new SectionUpdateHandler(){
 68  
 
 69  
                         @Override
 70  
                         public void onSectionUpdate(final SectionUpdateEvent event) {
 71  0
                                 LayoutController.this.requestModel(new ModelRequestCallback<DataModel>(){
 72  
 
 73  
                                         @Override
 74  
                                         public void onRequestFail(Throwable cause) {
 75  0
                                                 GWT.log("Unable to retrieve model for section update", cause);
 76  0
                                         }
 77  
 
 78  
                                         @Override
 79  
                                         public void onModelReady(DataModel model) {
 80  0
                                                 event.getSection().updateModel(model);
 81  0
                                                 event.getSection().updateWidgetData(model);
 82  
                                                 
 83  0
                                         }
 84  
                                 });
 85  
                                 
 86  0
                         }
 87  
                 });
 88  
                 //Global validation Event handling
 89  0
         addApplicationEventHandler(ValidateRequestEvent.TYPE, new ValidateRequestHandler() {
 90  
 
 91  
             @Override
 92  
             public void onValidateRequest(final ValidateRequestEvent event) {
 93  0
                     FieldDescriptor originatingField = event.getFieldDescriptor();
 94  0
                     String modelId = null;
 95  0
                     if (originatingField != null) {
 96  0
                             modelId = originatingField.getModelId();
 97  
                     }
 98  0
                     if (modelId == null) {
 99  0
                             requestModel(new ModelRequestCallback<DataModel>() {
 100  
                                     @Override
 101  
                                     public void onModelReady(DataModel model) {
 102  0
                                             validate(model, event);
 103  0
                                     }
 104  
 
 105  
                                     @Override
 106  
                                     public void onRequestFail(Throwable cause) {
 107  0
                                             GWT.log("Unable to retrieve model for validation", cause);
 108  0
                                     }
 109  
 
 110  
                             });
 111  
                     } else {
 112  0
                             requestModel(modelId, new ModelRequestCallback<DataModel>() {
 113  
                                     @Override
 114  
                                     public void onModelReady(DataModel model) {
 115  0
                                             validate(model, event);
 116  0
                                     }
 117  
 
 118  
                                     @Override
 119  
                                     public void onRequestFail(Throwable cause) {
 120  0
                                             GWT.log("Unable to retrieve model for validation", cause);
 121  0
                                     }
 122  
 
 123  
                             });
 124  
                     }
 125  0
             }
 126  
 
 127  
         });
 128  0
     }
 129  
     
 130  
     private void validate(DataModel model, final ValidateRequestEvent event) {
 131  0
             if(event.validateSingleField()){
 132  0
                     model.validateField(event.getFieldDescriptor(), new Callback<List<ValidationResultInfo>>() {
 133  
                 @Override
 134  
                 public void exec(List<ValidationResultInfo> result) {
 135  0
                         if(event.getFieldDescriptor() != null){
 136  
                                 //We dont need to traverse since it is single field, so don't do isValid call here
 137  
                                 //instead add the error messages directly
 138  0
                                 FieldElement element = event.getFieldDescriptor().getFieldElement();
 139  0
                                 if(element != null){
 140  0
                                         element.clearValidationPanel();
 141  0
                                         for(int i = 0; i < result.size(); i++){
 142  0
                                             ValidationResultInfo vr = result.get(i);
 143  0
                                             if(vr.getElement().equals(event.getFieldDescriptor().getFieldKey()) 
 144  
                                                             && event.getFieldDescriptor().hasHadFocus()){
 145  0
                                                                     element.processValidationResult(vr);
 146  
                                             }
 147  
                                     }
 148  
                                 }
 149  
                         }
 150  
                         
 151  0
                 }
 152  
                     });
 153  
             }
 154  
             else{
 155  0
             model.validate(new Callback<List<ValidationResultInfo>>() {
 156  
                 @Override
 157  
                 public void exec(List<ValidationResultInfo> result) {
 158  0
                     isValid(result, false, true);
 159  0
                 }
 160  
             });
 161  
             }
 162  0
     }
 163  
     
 164  
     public ErrorLevel checkForErrors(List<ValidationResultInfo> list){
 165  0
                 ErrorLevel errorLevel = ErrorLevel.OK;
 166  
                 
 167  0
                 for(ValidationResultInfo vr: list){
 168  0
                         if(vr.getErrorLevel().getLevel() > errorLevel.getLevel()){
 169  0
                                 errorLevel = vr.getErrorLevel();
 170  
                         }
 171  0
                         if(errorLevel.equals(ErrorLevel.ERROR)){
 172  0
                                 break;
 173  
                         }
 174  
                 }
 175  
             
 176  0
             return errorLevel;
 177  
             
 178  
     }
 179  
     
 180  
     public static LayoutController findParentLayout(Widget w){
 181  0
         LayoutController result = null;
 182  
         while (true) {
 183  0
             if (w == null) {
 184  0
                 break;
 185  0
             } else if (w instanceof HasLayoutController) {
 186  0
                     result = ((HasLayoutController)w).getLayoutController();
 187  0
                     if (result != null) {
 188  0
                             break;
 189  
                     }
 190  0
             } else if (w instanceof LayoutController) {
 191  0
                 result = (LayoutController) w;
 192  0
                 break;
 193  
             }
 194  0
             w = w.getParent();
 195  
             
 196  
         }
 197  0
         return result;
 198  
     }
 199  
     
 200  
         public void addStartViewPopup(final View view){
 201  0
             startPopupView = view;
 202  0
             if(startViewWindow == null){
 203  0
                     startViewWindow = new KSLightBox();
 204  
             }
 205  
 
 206  0
             FlowPanel panel = new FlowPanel();
 207  0
             panel.add(view.asWidget());
 208  0
             KSButton save = new KSButton("Save",new ClickHandler(){
 209  
             public void onClick(ClickEvent event) {
 210  0
                 view.updateModel();
 211  0
                 SaveActionEvent saveActionEvent = new SaveActionEvent(true);
 212  
 
 213  0
                 saveActionEvent.setActionCompleteCallback(new ActionCompleteCallback(){
 214  
                     public void onActionComplete(ActionEvent action) {
 215  0
                         startViewWindow.hide();
 216  0
                     }
 217  
                 });
 218  
                 
 219  
 
 220  0
                 fireApplicationEvent(saveActionEvent);
 221  0
             }
 222  
             });
 223  0
             startViewWindow.addButton(save);
 224  
             
 225  0
             KSButton cancel = new KSButton("Cancel", new ClickHandler(){
 226  
             public void onClick(ClickEvent event) {
 227  0
                 startViewWindow.hide();
 228  0
             }
 229  
             });
 230  0
             startViewWindow.addButton(cancel);
 231  
 
 232  0
             if(view instanceof SectionView){
 233  0
                     ((SectionView) view).setController(this);
 234  
             }
 235  0
             startViewWindow.setWidget(panel);
 236  0
         }
 237  
         
 238  
     public boolean isStartViewShowing(){
 239  0
         if(startViewWindow == null){
 240  0
             return false;
 241  
         }
 242  0
             return startViewWindow.isShowing();
 243  
     }
 244  
 
 245  
     public View getStartPopupView(){
 246  0
         return startPopupView;
 247  
     }
 248  
     
 249  
     public void showStartPopup(final Callback<Boolean> onReadyCallback){
 250  0
         startPopupView.beforeShow(new Callback<Boolean>() {
 251  
                         @Override
 252  
                         public void exec(Boolean result) {
 253  0
                                 if (result) {
 254  0
                                         startViewWindow.show();
 255  
                                 }
 256  0
                                 onReadyCallback.exec(result);
 257  0
                         }
 258  
         });
 259  0
     }
 260  
     
 261  
     public KSLightBox getStartPopup(){
 262  0
         return startViewWindow;
 263  
     }
 264  
 
 265  
 
 266  
     /*New methods*/
 267  
         
 268  
         public void addView(View view){
 269  0
                 viewMap.put(view.getViewEnum(), view);
 270  0
                 viewEnumMap.put(view.getViewEnum().toString(), view.getViewEnum());
 271  0
                 if(view instanceof SectionView){
 272  0
                         ((SectionView) view).setController(this);
 273  
                 }
 274  0
                 else if(view instanceof ToolView){
 275  0
                         ((ToolView) view).setController(this);
 276  
                 }
 277  0
         }
 278  
         
 279  
         public <V extends Enum<?>> void setDefaultView(V viewType){
 280  0
                 this.defaultView = viewType;
 281  0
         }
 282  
         
 283  
         public Enum<?> getDefaultView(){
 284  0
                 return this.defaultView;
 285  
         }
 286  
         
 287  
         public abstract void updateModel();
 288  
         
 289  
         public void updateModelFromView(Enum<?> viewType){
 290  0
                 View v = viewMap.get(viewType);
 291  0
                 if(v != null){
 292  0
                         v.updateModel();
 293  
                 }
 294  0
         }
 295  
         
 296  
         public void updateModelFromCurrentView(){
 297  0
         if(this.getCurrentView() != null){
 298  0
                     this.getCurrentView().updateModel();
 299  
         }
 300  0
         }
 301  
 
 302  
 
 303  
         @Override
 304  
         public <V extends Enum<?>> void getView(V viewType, Callback<View> callback) {
 305  0
                 callback.exec(viewMap.get(viewType));
 306  0
         }
 307  
 
 308  
         @Override
 309  
         public Enum<?> getViewEnumValue(String enumValue) {
 310  0
                 return viewEnumMap.get(enumValue);
 311  
         }
 312  
 
 313  
         //TODO remove this method from controller hierarchy?  its not used
 314  
         @Override
 315  
         public Class<? extends Enum<?>> getViewsEnum() {
 316  0
                 return null;
 317  
         }
 318  
 
 319  
         @Override
 320  
         public void showDefaultView(final Callback<Boolean> onReadyCallback) {
 321  0
                 HistoryManager.setLogNavigationHistory(false);
 322  
                 //turn of history support for default showing until view is ready
 323  0
                 if(defaultView != null){
 324  0
                         showView(defaultView, onReadyCallback);
 325  
                 }
 326  0
                 else if(!viewMap.isEmpty()){                
 327  0
                         if(defaultView == null){
 328  0
                                 showView(viewMap.entrySet().iterator().next().getKey(), onReadyCallback);
 329  
                         }        
 330  
                 }
 331  
                 
 332  0
         }
 333  
         
 334  
         public void showFirstView(Callback<Boolean> onReadyCallback){
 335  0
                 HistoryManager.setLogNavigationHistory(false);
 336  0
                 if(!viewMap.isEmpty()){        
 337  0
                         showView(viewMap.entrySet().iterator().next().getKey(), onReadyCallback);
 338  
                 }
 339  
                 else{
 340  0
                         showDefaultView(onReadyCallback);
 341  
                 }
 342  0
         }
 343  
         
 344  
         /**
 345  
           * Check to see if current/all section(s) is valid (ie. does not contain any errors)
 346  
           *
 347  
          * @param validationResults List of validation results for the layouts model.
 348  
          * @param checkCurrentSectionOnly true if errors should be checked on current section only, false if all sections should be checked
 349  
          * @return true if the specified sections (all or current) has any validation errors
 350  
          */
 351  
         public boolean isValid(List<ValidationResultInfo> validationResults, boolean checkCurrentSectionOnly){
 352  0
                 return isValid(validationResults, checkCurrentSectionOnly, true);
 353  
         }
 354  
         
 355  
         public boolean isValid(List<ValidationResultInfo> validationResults, boolean checkCurrentSectionOnly, boolean allFields){
 356  0
                 boolean isValid = true;
 357  
 
 358  0
                 if (checkCurrentSectionOnly){
 359  
                         //Check for validation errors on the currently displayed section only
 360  0
                     View v = getCurrentView();
 361  0
                 if(v instanceof Section){
 362  0
                         isValid = isValid(validationResults, (Section)v, allFields);
 363  
                     }
 364  0
                      if(this.isStartViewShowing()){
 365  0
                              if(startPopupView instanceof Section){
 366  0
                                      isValid = isValid(validationResults, ((Section) startPopupView), allFields) && isValid;
 367  
                              }
 368  
                      }
 369  0
                 } else {
 370  
                         //Check for validation errors on all sections
 371  0
                         String errorSections = "";
 372  0
                         StringBuilder errorSectionsbuffer = new StringBuilder();
 373  0
                         errorSectionsbuffer.append(errorSections);
 374  0
                         for (Entry<Enum<?>, View> entry:viewMap.entrySet()) {
 375  0
                                 View v = entry.getValue();
 376  0
                                 if (v instanceof Section){
 377  0
                                         if (!isValid(validationResults, (Section)v, allFields)){
 378  0
                                                 isValid = false;
 379  0
                                                 errorSectionsbuffer.append(((SectionView)v).getName() + ", ");
 380  
                                         }
 381  
                                 }
 382  0
                         }
 383  0
                      if(this.isStartViewShowing()){
 384  0
                              if(startPopupView instanceof Section){
 385  0
                                      isValid = isValid(validationResults, ((Section) startPopupView), allFields) && isValid;
 386  
                              }
 387  
                      }
 388  0
                         errorSections = errorSectionsbuffer.toString();
 389  0
                         if (!errorSections.isEmpty()){
 390  0
                                 errorSections = errorSections.substring(0, errorSections.length()-2);
 391  
                                 //container.addMessage("Following section(s) has errors & must be corrected: " + errorSections);
 392  
                         }
 393  
                 }
 394  
 
 395  0
                 return isValid;
 396  
         }
 397  
 
 398  
         private boolean isValid(List<ValidationResultInfo> validationResults, Section section, boolean allFields){
 399  
                 ErrorLevel status;
 400  0
                 if(allFields){
 401  0
                         section.setFieldHasHadFocusFlags(true);
 402  0
                         status = section.processValidationResults(validationResults);
 403  
                 }
 404  
                 else{
 405  0
                         status = section.processValidationResults(validationResults, false);
 406  
                 }
 407  
 
 408  0
                 return (status != ErrorLevel.ERROR);
 409  
         }
 410  
         
 411  
         @Override
 412  
         public void beforeViewChange(Enum<?> viewChangingTo, Callback<Boolean> okToChange) {
 413  0
                 if(this.getCurrentView() instanceof Controller){
 414  0
                         ((Controller)this.getCurrentView()).beforeViewChange(viewChangingTo, okToChange);
 415  
                 }
 416  
                 else{
 417  0
                         okToChange.exec(true);
 418  
                 }
 419  0
         }
 420  
 
 421  
         @Override
 422  
         public Widget asWidget() {
 423  0
                 return this;
 424  
         }
 425  
 
 426  
         @Override
 427  
         public boolean beforeHide() {
 428  0
                 return true;
 429  
         }
 430  
 
 431  
         @Override
 432  
         public void beforeShow(Callback<Boolean> onReadyCallback) {
 433  0
                 onReadyCallback.exec(true);
 434  0
         }
 435  
 
 436  
         @Override
 437  
         public Controller getController() {
 438  0
                 return parentController;
 439  
         }
 440  
 
 441  
         @Override
 442  
         public String getName() {
 443  0
                 if(name == null && viewType != null){
 444  0
                         return viewType.toString();
 445  
                 }
 446  
                 else{
 447  0
                         return name;
 448  
                 }
 449  
         }
 450  
 
 451  
         @Override
 452  
         public Enum<?> getViewEnum() {
 453  0
                 return viewType;
 454  
         }
 455  
         
 456  
         public void setViewEnum(Enum<?> viewType){
 457  0
                 this.viewType= viewType;
 458  0
         }
 459  
         
 460  
         public void setName(String name){
 461  0
                 this.name = name;
 462  0
         }
 463  
         
 464  
         public void setController(Controller controller){
 465  0
                 parentController = controller;
 466  0
         }
 467  
         
 468  
         @Override
 469  
         public void collectBreadcrumbNames(List<String> names) {
 470  0
                 names.add(this.getName());
 471  0
                 if(this.getCurrentView() != null){
 472  0
                         this.getCurrentView().collectBreadcrumbNames(names);
 473  
                 }
 474  0
         }
 475  
         
 476  
         @Override
 477  
         public void clear() {
 478  
                 
 479  0
         }
 480  
         
 481  
 }