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