Coverage Report - org.kuali.student.lum.program.client.ProgramController
 
Classes in this File Line Coverage Branch Coverage Complexity
ProgramController
0%
0/126
0%
0/40
1.861
ProgramController$1
0%
0/11
0%
0/6
1.861
ProgramController$1$1
0%
0/14
0%
0/4
1.861
ProgramController$2
0%
0/5
0%
0/4
1.861
ProgramController$3
0%
0/9
N/A
1.861
ProgramController$4
0%
0/7
0%
0/2
1.861
ProgramController$5
0%
0/10
N/A
1.861
ProgramController$6
0%
0/3
N/A
1.861
ProgramController$7
0%
0/1
N/A
1.861
 
 1  
 package org.kuali.student.lum.program.client;
 2  
 
 3  
 import com.google.gwt.core.client.GWT;
 4  
 import com.google.gwt.event.dom.client.ClickEvent;
 5  
 import com.google.gwt.event.dom.client.ClickHandler;
 6  
 import com.google.gwt.event.shared.HandlerManager;
 7  
 import com.google.gwt.user.client.ui.Label;
 8  
 import com.google.gwt.user.client.ui.Widget;
 9  
 import org.kuali.student.common.ui.client.application.ViewContext;
 10  
 import org.kuali.student.common.ui.client.configurable.mvc.layouts.MenuSectionController;
 11  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
 12  
 import org.kuali.student.common.ui.client.configurable.mvc.views.SectionView;
 13  
 import org.kuali.student.common.ui.client.mvc.*;
 14  
 import org.kuali.student.common.ui.client.mvc.dto.ReferenceModel;
 15  
 import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
 16  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 17  
 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract;
 18  
 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations;
 19  
 import org.kuali.student.common.ui.client.widgets.commenttool.CommentTool;
 20  
 import org.kuali.student.common.ui.client.widgets.dialog.ButtonMessageDialog;
 21  
 import org.kuali.student.common.ui.client.widgets.field.layout.button.ButtonGroup;
 22  
 import org.kuali.student.common.ui.client.widgets.field.layout.button.YesNoCancelGroup;
 23  
 import org.kuali.student.common.ui.shared.IdAttributes;
 24  
 import org.kuali.student.common.ui.shared.IdAttributes.IdType;
 25  
 import org.kuali.student.core.assembly.data.Data;
 26  
 import org.kuali.student.core.assembly.data.Metadata;
 27  
 import org.kuali.student.core.dto.DtoConstants;
 28  
 import org.kuali.student.core.rice.authorization.PermissionType;
 29  
 import org.kuali.student.lum.common.client.helpers.RecentlyViewedHelper;
 30  
 import org.kuali.student.lum.common.client.widgets.AppLocations;
 31  
 import org.kuali.student.lum.program.client.events.ModelLoadedEvent;
 32  
 import org.kuali.student.lum.program.client.events.UpdateEvent;
 33  
 import org.kuali.student.lum.program.client.properties.ProgramProperties;
 34  
 import org.kuali.student.lum.program.client.rpc.AbstractCallback;
 35  
 import org.kuali.student.lum.program.client.rpc.MajorDisciplineRpcService;
 36  
 import org.kuali.student.lum.program.client.rpc.MajorDisciplineRpcServiceAsync;
 37  
 import org.kuali.student.lum.program.client.widgets.ProgramSideBar;
 38  
 
 39  
 import java.util.HashMap;
 40  
 import java.util.Map;
 41  
 
 42  
 /**
 43  
  * @author Igor
 44  
  */
 45  0
 public abstract class ProgramController extends MenuSectionController {
 46  
 
 47  
     protected MajorDisciplineRpcServiceAsync programRemoteService;
 48  
 
 49  0
     protected boolean initialized = false;
 50  
 
 51  
     protected DataModel programModel;
 52  
 
 53  
     protected AbstractProgramConfigurer configurer;
 54  
 
 55  
     protected HandlerManager eventBus;
 56  
 
 57  0
     protected Label statusLabel = new Label();
 58  
 
 59  
     protected ProgramSideBar sideBar;
 60  
 
 61  0
     private boolean needToLoadOldModel = false;
 62  
 
 63  
     private ProgramStatus lastLoadedStatus;
 64  
 
 65  0
     protected boolean reloadMetadata = false;
 66  
 
 67  0
     protected boolean processBeforeShow = true;
 68  
 
 69  
     /**
 70  
      * Constructor.
 71  
      *
 72  
      * @param programModel
 73  
      */
 74  
     public ProgramController(String name, DataModel programModel, ViewContext viewContext, HandlerManager eventBus) {
 75  0
         super(name);
 76  0
         programRemoteService = createProgramRemoteService();
 77  0
         this.eventBus = eventBus;
 78  0
         this.programModel = programModel;
 79  0
         setViewContext(viewContext);
 80  0
         initializeModel();
 81  0
     }
 82  
 
 83  
 
 84  
     /**
 85  
      * Create a ProgramRpcServiceAsync appropriate for this Controller
 86  
      */
 87  
     protected MajorDisciplineRpcServiceAsync createProgramRemoteService() {
 88  0
         return GWT.create(MajorDisciplineRpcService.class);
 89  
     }
 90  
 
 91  
     @Override
 92  
     public void beforeViewChange(Enum<?> viewChangingTo, final Callback<Boolean> okToChange) {
 93  0
         if (processBeforeShow) {
 94  0
             super.beforeViewChange(viewChangingTo, new Callback<Boolean>() {
 95  
 
 96  
                 @Override
 97  
                 public void exec(Boolean result) {
 98  0
                     if (result) {
 99  0
                         if (getCurrentView() instanceof SectionView && ((SectionView) getCurrentView()).isDirty()) {
 100  0
                             ButtonGroup<ButtonEnumerations.YesNoCancelEnum> buttonGroup = new YesNoCancelGroup();
 101  0
                             final ButtonMessageDialog<ButtonEnumerations.YesNoCancelEnum> dialog = new ButtonMessageDialog<ButtonEnumerations.YesNoCancelEnum>("Warning", "You may have unsaved changes.  Save changes?", buttonGroup);
 102  0
                             buttonGroup.addCallback(new Callback<ButtonEnumerations.YesNoCancelEnum>() {
 103  
 
 104  
                                 @Override
 105  
                                 public void exec(ButtonEnumerations.YesNoCancelEnum result) {
 106  0
                                     switch (result) {
 107  
                                         case YES:
 108  0
                                             dialog.hide();
 109  0
                                             fireUpdateEvent(okToChange);
 110  0
                                             break;
 111  
                                         case NO:
 112  0
                                             dialog.hide();
 113  0
                                             resetModel();
 114  0
                                             needToLoadOldModel = true;
 115  0
                                             resetFieldInteractionFlag();
 116  0
                                             okToChange.exec(true);
 117  0
                                             break;
 118  
                                         case CANCEL:
 119  0
                                             okToChange.exec(false);
 120  0
                                             dialog.hide();
 121  
                                             break;
 122  
                                     }
 123  0
                                 }
 124  
                             });
 125  0
                             dialog.show();
 126  0
                         } else {
 127  0
                             okToChange.exec(true);
 128  
                         }
 129  
                     } else {
 130  0
                         okToChange.exec(false);
 131  
                     }
 132  0
                 }
 133  
             });
 134  
         } else {
 135  0
             processBeforeShow = true;
 136  
         }
 137  0
     }
 138  
 
 139  
     protected void fireUpdateEvent(final Callback<Boolean> okToChange) {
 140  0
         eventBus.fireEvent(new UpdateEvent(okToChange));
 141  0
     }
 142  
 
 143  
     protected void resetModel() {
 144  0
         programModel.resetRoot();
 145  0
     }
 146  
 
 147  
     protected void resetFieldInteractionFlag() {
 148  0
         View currentView = getCurrentView();
 149  0
         if (currentView instanceof Section) {
 150  0
             ((Section) currentView).resetFieldInteractionFlags();
 151  
         }
 152  0
     }
 153  
 
 154  
     /**
 155  
      * Initialized model of the controller.
 156  
      */
 157  
     private void initializeModel() {
 158  0
         setDefaultModelId(ProgramConstants.PROGRAM_MODEL_ID);
 159  0
         registerModel(ProgramConstants.PROGRAM_MODEL_ID, new ModelProvider<DataModel>() {
 160  
             @Override
 161  
             public void requestModel(final ModelRequestCallback<DataModel> callback) {
 162  0
                 if (programModel.getRoot() == null || programModel.getRoot().size() == 0) {
 163  0
                     loadModel(callback);
 164  
                 } else {
 165  0
                     callback.onModelReady(programModel);
 166  
                 }
 167  0
             }
 168  
         });
 169  0
     }
 170  
 
 171  
 
 172  
     @Override
 173  
     public void requestModel(Class modelType, ModelRequestCallback callback) {
 174  0
         if (modelType == ReferenceModel.class) {
 175  0
             ReferenceModel referenceModel = new ReferenceModel();
 176  0
             referenceModel.setReferenceId(ProgramUtils.getProgramId(programModel));
 177  0
             referenceModel.setReferenceTypeKey(ProgramConstants.MAJOR_REFERENCE_TYPE_ID);
 178  0
             referenceModel.setReferenceType(ProgramConstants.MAJOR_LU_TYPE_ID);
 179  0
             Map<String, String> attributes = new HashMap<String, String>();
 180  0
             attributes.put("name", getStringProperty("name"));
 181  0
             referenceModel.setReferenceAttributes(attributes);
 182  0
             callback.onModelReady(referenceModel);
 183  0
         } else {
 184  0
             super.requestModel(modelType, callback);
 185  
         }
 186  0
     }
 187  
 
 188  
 
 189  
     /**
 190  
      * Loads data model from the server.
 191  
      *
 192  
      * @param callback we have to invoke this callback when model is loaded or failed.
 193  
      */
 194  
     protected void loadModel(final ModelRequestCallback<DataModel> callback) {
 195  0
         programRemoteService.getData(getViewContext().getId(), new AbstractCallback<Data>(ProgramProperties.get().common_retrievingData()) {
 196  
 
 197  
             @Override
 198  
             public void onFailure(Throwable caught) {
 199  0
                 super.onFailure(caught);
 200  0
                 callback.onRequestFail(caught);
 201  0
             }
 202  
 
 203  
             @Override
 204  
             public void onSuccess(Data result) {
 205  0
                 super.onSuccess(result);
 206  0
                 programModel.setRoot(result);
 207  0
                 setHeaderTitle();
 208  0
                 callback.onModelReady(programModel);
 209  0
             }
 210  
         });
 211  0
     }
 212  
 
 213  
     private void setModelData() {
 214  0
         setHeaderTitle();
 215  0
         setStatus();
 216  0
         configurer.applyPermissions();
 217  
         //We don't want to throw ModelLoadedEvent when we just want to rollback the model
 218  0
         if (needToLoadOldModel) {
 219  0
             needToLoadOldModel = false;
 220  
         } else {
 221  0
             String id = ProgramUtils.getProgramId(programModel);
 222  0
             if (null != id) {
 223  
                 // add to recently viewed
 224  0
                 ViewContext docContext = new ViewContext();
 225  0
                 docContext.setId(id);
 226  0
                 docContext.setIdType(IdType.OBJECT_ID);
 227  0
                 String pgmType = getStringProperty(ProgramConstants.TYPE);
 228  0
                 docContext.setAttribute(ProgramConstants.TYPE, pgmType + '/' + ProgramSections.PROGRAM_DETAILS_VIEW);
 229  0
                 RecentlyViewedHelper.addDocument(getProgramName(),
 230  
                         HistoryManager.appendContext(getProgramViewLocation(pgmType), docContext));
 231  
             }
 232  0
             eventBus.fireEvent(new ModelLoadedEvent(programModel));
 233  0
             onModelLoadedEvent();
 234  
         }
 235  0
     }
 236  
 
 237  
     private String getProgramViewLocation(String pgmType) {
 238  0
         if (ProgramClientConstants.MAJOR_PROGRAM.equals(pgmType)) {
 239  0
             return AppLocations.Locations.VIEW_PROGRAM.getLocation();
 240  0
         } else if (ProgramClientConstants.CORE_PROGRAM.equals(pgmType)) {
 241  0
             return AppLocations.Locations.VIEW_CORE_PROGRAM.getLocation();
 242  0
         } else if (ProgramClientConstants.CREDENTIAL_PROGRAM_TYPES.contains(pgmType)) {
 243  0
             return AppLocations.Locations.VIEW_BACC_PROGRAM.getLocation();
 244  
         }
 245  0
         return null;
 246  
     }
 247  
 
 248  
     protected void setStatus() {
 249  0
         statusLabel.setText(ProgramProperties.get().common_status(getStringProperty(ProgramConstants.STATE)));
 250  0
     }
 251  
 
 252  
     public String getProgramName() {
 253  0
         String name = getStringProperty(ProgramConstants.LONG_TITLE);
 254  0
         if (name == null) {
 255  0
             name = ProgramProperties.get().common_newProgram();
 256  
         }
 257  0
         return name;
 258  
     }
 259  
 
 260  
     /**
 261  
      * Got invoked by framework before showing the view of the controller.
 262  
      *
 263  
      * @param onReadyCallback
 264  
      */
 265  
     @Override
 266  
     public void beforeShow(final Callback<Boolean> onReadyCallback) {
 267  0
         if (programModel.getRoot() == null) {
 268  0
             loadModel(new ModelRequestCallback<DataModel>() {
 269  
                 @Override
 270  
                 public void onModelReady(DataModel model) {
 271  0
                     if (loadMetadataCondition()) {
 272  0
                         loadMetadata(onReadyCallback);
 273  
                     } else {
 274  
 
 275  0
                         onReadyCallback.exec(true);
 276  
                     }
 277  0
                 }
 278  
 
 279  
                 @Override
 280  
                 public void onRequestFail(Throwable cause) {
 281  0
                     GWT.log(cause.getMessage());
 282  0
                 }
 283  
             });
 284  
         } else {
 285  0
             afterMetadataLoaded(onReadyCallback);
 286  
         }
 287  0
     }
 288  
 
 289  
     /**
 290  
      * We should only load metadata if the status of model is changed.
 291  
      *
 292  
      * @return
 293  
      */
 294  
     protected boolean loadMetadataCondition() {
 295  0
         return lastLoadedStatus == null || ProgramStatus.of(programModel) != lastLoadedStatus;
 296  
     }
 297  
 
 298  
     /**
 299  
      * Loads metadata from the server.
 300  
      *
 301  
      * @param onReadyCallback
 302  
      */
 303  
     protected void loadMetadata(final Callback<Boolean> onReadyCallback) {
 304  0
         Map<String, String> idAttributes = new HashMap<String, String>();
 305  0
         ViewContext viewContext = getViewContext();
 306  0
         IdType idType = viewContext.getIdType();
 307  0
         String viewContextId = null;
 308  0
         if (idType != null) {
 309  0
             idAttributes.put(IdAttributes.ID_TYPE, idType.toString());
 310  0
             viewContextId = viewContext.getId();
 311  0
             if (idType == IdType.COPY_OF_OBJECT_ID) {
 312  0
                 viewContextId = null;
 313  
             }
 314  
         }
 315  0
         if (programModel.getRoot() != null) {
 316  0
             ProgramStatus programStatus = ProgramStatus.of(programModel);
 317  0
             idAttributes.put(DtoConstants.DTO_STATE, programStatus.getValue());
 318  0
             if (programStatus.getNextStatus() != null) {
 319  0
                 idAttributes.put(DtoConstants.DTO_NEXT_STATE, programStatus.getNextStatus().getValue());
 320  
             }
 321  
         }
 322  0
         programRemoteService.getMetadata(viewContextId, idAttributes, new AbstractCallback<Metadata>() {
 323  
 
 324  
             @Override
 325  
             public void onSuccess(Metadata result) {
 326  0
                 super.onSuccess(result);
 327  0
                 DataModelDefinition def = new DataModelDefinition(result);
 328  0
                 programModel.setDefinition(def);
 329  0
                 lastLoadedStatus = ProgramStatus.of(programModel);
 330  0
                 afterMetadataLoaded(onReadyCallback);
 331  0
             }
 332  
 
 333  
             @Override
 334  
             public void onFailure(Throwable caught) {
 335  0
                 super.onFailure(caught);
 336  0
                 onReadyCallback.exec(false);
 337  0
             }
 338  
         });
 339  0
     }
 340  
 
 341  
     protected void configureView() {
 342  0
         addStyleName("programController");
 343  0
         configurer.setModelDefinition(programModel.getDefinition());
 344  0
         configurer.configure(this);
 345  0
         addContentWidget(statusLabel);
 346  0
         setSideBarWidget(sideBar);
 347  0
     }
 348  
 
 349  
     @Override
 350  
     public void setViewContext(ViewContext viewContext) {
 351  0
         super.setViewContext(viewContext);
 352  0
         if (viewContext.getId() != null && !viewContext.getId().isEmpty()) {
 353  0
             viewContext.setPermissionType(PermissionType.OPEN);
 354  
         } else {
 355  0
             viewContext.setPermissionType(PermissionType.INITIATE);
 356  
         }
 357  0
     }
 358  
 
 359  
     /**
 360  
      * Called when metadata is loaded.
 361  
      *
 362  
      * @param onReadyCallback
 363  
      */
 364  
     protected void afterMetadataLoaded(Callback<Boolean> onReadyCallback) {
 365  0
         if (!reloadMetadata) {
 366  0
             configureView();
 367  0
             onReadyCallback.exec(true);
 368  0
             reloadMetadata = true;
 369  
         } else {
 370  0
             onReadyCallback.exec(true);
 371  0
             ProgramUtils.syncMetadata(configurer, programModel.getDefinition());
 372  
         }
 373  0
         if (programModel.getRoot() != null) {
 374  0
             setModelData();
 375  
         }
 376  0
     }
 377  
 
 378  
     protected void setHeaderTitle() {
 379  0
         String title = getProgramName();
 380  0
         this.setContentTitle(title);
 381  0
         this.setName(title);
 382  0
     }
 383  
 
 384  
     protected Widget createCommentPanel() {
 385  0
         final CommentTool commentTool = new CommentTool(ProgramSections.COMMENTS, "Comments", "kuali.comment.type.generalRemarks", "Program Comments");
 386  0
         commentTool.setController(this);
 387  0
         KSButton commentsButton = new KSButton(ProgramProperties.get().comments_button(), KSButtonAbstract.ButtonStyle.DEFAULT_ANCHOR, new ClickHandler() {
 388  
 
 389  
             @Override
 390  
             public void onClick(ClickEvent event) {
 391  0
                 commentTool.show();
 392  0
             }
 393  
         });
 394  0
         return commentsButton;
 395  
     }
 396  
 
 397  
     protected void doSave() {
 398  0
     }
 399  
 
 400  
     public DataModel getProgramModel() {
 401  0
         return programModel;
 402  
     }
 403  
 
 404  
     public void onModelLoadedEvent() {
 405  0
     }
 406  
 
 407  
     protected String getStringProperty(String key) {
 408  0
         return programModel.get(key);
 409  
     }
 410  
 
 411  
     protected Data getDataProperty(String key) {
 412  0
         return programModel.get(key);
 413  
     }
 414  
 }