View Javadoc

1   package org.kuali.student.lum.program.client.credential.edit;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.kuali.student.common.assembly.data.Data;
7   import org.kuali.student.common.assembly.data.QueryPath;
8   import org.kuali.student.common.ui.client.application.Application;
9   import org.kuali.student.common.ui.client.application.ViewContext;
10  import org.kuali.student.common.ui.client.mvc.Callback;
11  import org.kuali.student.common.ui.client.mvc.DataModel;
12  import org.kuali.student.common.ui.client.mvc.HasCrossConstraints;
13  import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
14  import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
15  import org.kuali.student.common.ui.client.service.DataSaveResult;
16  import org.kuali.student.common.ui.client.validator.ValidatorClientUtils;
17  import org.kuali.student.common.ui.client.widgets.KSButton;
18  import org.kuali.student.common.ui.client.widgets.KSButtonAbstract;
19  import org.kuali.student.common.ui.client.widgets.notification.KSNotification;
20  import org.kuali.student.common.ui.client.widgets.notification.KSNotifier;
21  import org.kuali.student.common.ui.shared.IdAttributes.IdType;
22  import org.kuali.student.common.validation.dto.ValidationResultInfo;
23  import org.kuali.student.lum.common.client.widgets.AppLocations;
24  import org.kuali.student.lum.program.client.ProgramConstants;
25  import org.kuali.student.lum.program.client.ProgramMsgConstants;
26  import org.kuali.student.lum.program.client.ProgramRegistry;
27  import org.kuali.student.lum.program.client.ProgramSections;
28  import org.kuali.student.lum.program.client.ProgramUtils;
29  import org.kuali.student.lum.program.client.credential.CredentialController;
30  import org.kuali.student.lum.program.client.events.AfterSaveEvent;
31  import org.kuali.student.lum.program.client.events.ChangeViewEvent;
32  import org.kuali.student.lum.program.client.events.MetadataLoadedEvent;
33  import org.kuali.student.lum.program.client.events.ModelLoadedEvent;
34  import org.kuali.student.lum.program.client.events.StateChangeEvent;
35  import org.kuali.student.lum.program.client.events.StoreRequirementIDsEvent;
36  import org.kuali.student.lum.program.client.events.UpdateEvent;
37  import org.kuali.student.lum.program.client.rpc.AbstractCallback;
38  
39  import com.google.gwt.core.client.GWT;
40  import com.google.gwt.event.dom.client.ClickEvent;
41  import com.google.gwt.event.dom.client.ClickHandler;
42  import com.google.gwt.event.shared.HandlerManager;
43  import com.google.gwt.user.client.Window;
44  
45  /**
46   * @author Igor
47   */
48  public class CredentialEditController extends CredentialController {
49  
50      private final KSButton saveButton = new KSButton(getLabel(ProgramMsgConstants.COMMON_SAVE));
51      private final KSButton cancelButton = new KSButton(getLabel(ProgramMsgConstants.COMMON_CANCEL), KSButtonAbstract.ButtonStyle.ANCHOR_LARGE_CENTERED);
52  
53      /**
54       * Constructor.
55       *
56       * @param programModel
57       */
58      public CredentialEditController(DataModel programModel, ViewContext viewContext, HandlerManager eventBus) {
59          super(programModel, viewContext, eventBus);
60          configurer = GWT.create(CredentialEditConfigurer.class);
61          bind();
62      }
63  
64      @Override
65      protected void configureView() {
66          super.configureView();
67          if (!initialized) {
68              eventBus.fireEvent(new MetadataLoadedEvent(programModel.getDefinition(), this));
69              List<Enum<?>> excludedViews = new ArrayList<Enum<?>>();
70              excludedViews.add(ProgramSections.PROGRAM_REQUIREMENTS_EDIT);
71              excludedViews.add(ProgramSections.SUPPORTING_DOCUMENTS_EDIT);
72              excludedViews.add(ProgramSections.SUMMARY);
73              addCommonButton(getLabel(ProgramMsgConstants.PROGRAM_MENU_SECTIONS), saveButton, excludedViews);
74              addCommonButton(getLabel(ProgramMsgConstants.PROGRAM_MENU_SECTIONS), cancelButton, excludedViews);
75              initialized = true;
76          }
77      }
78  
79      private void bind() {
80          saveButton.addClickHandler(new ClickHandler() {
81  
82              @Override
83              public void onClick(ClickEvent event) {
84                  doSave();
85              }
86          });
87          cancelButton.addClickHandler(new ClickHandler() {
88  
89              @Override
90              public void onClick(ClickEvent event) {
91                  doCancel();
92              }
93          });
94          eventBus.addHandler(StoreRequirementIDsEvent.TYPE, new StoreRequirementIDsEvent.Handler() {
95              @Override
96              public void onEvent(StoreRequirementIDsEvent event) {
97                  List<String> ids = event.getProgramRequirementIds();
98  
99                  programModel.set(QueryPath.parse(ProgramConstants.PROGRAM_REQUIREMENTS), new Data());
100                 Data programRequirements = getDataProperty(ProgramConstants.PROGRAM_REQUIREMENTS);
101 
102                 if (programRequirements == null) {
103                     Window.alert("Cannot find program requirements in data model.");
104                     GWT.log("Cannot find program requirements in data model", null);
105                     return;
106                 }
107 
108                 for (String id : ids) {
109                     programRequirements.add(id);
110                 }
111                 doSave();
112             }
113         });
114         eventBus.addHandler(ChangeViewEvent.TYPE, new ChangeViewEvent.Handler() {
115             @Override
116             public void onEvent(ChangeViewEvent event) {
117                 showView(event.getViewToken());
118             }
119         });
120         eventBus.addHandler(UpdateEvent.TYPE, new UpdateEvent.Handler() {
121             @Override
122             public void onEvent(UpdateEvent event) {
123                 doSave(event.getOkCallback());
124             }
125         });
126         eventBus.addHandler(StateChangeEvent.TYPE, new StateChangeEvent.Handler() {
127             @Override
128             public void onEvent(final StateChangeEvent event) {
129                 programModel.validateNextState(new Callback<List<ValidationResultInfo>>() {
130                     @Override
131                     public void exec(List<ValidationResultInfo> result) {
132                         boolean isSectionValid = isValid(result, true);
133                         if (isSectionValid) {
134                             Callback<Boolean> callback = new Callback<Boolean>() {
135                                 @Override
136                                 public void exec(Boolean result) {
137                                     if (result) {
138                                         reloadMetadata = true;
139                                         loadMetadata(new Callback<Boolean>() {
140                                             @Override
141                                             public void exec(Boolean result) {
142                                                 if (result) {
143                                                     ProgramUtils.syncMetadata(configurer, programModel.getDefinition());
144                                                     HistoryManager.navigate(AppLocations.Locations.VIEW_BACC_PROGRAM.getLocation(), context);
145                                                 }
146                                             }
147                                         });
148                                     }
149                                 }
150                             };
151                             updateState(event.getProgramStatus().getValue(), callback);
152                         } else {
153                             KSNotifier.add(new KSNotification("Unable to save, please check fields for errors.", false, true, 5000));
154                         }
155                     }
156                 });
157             }
158         });
159     }
160 
161     private void doCancel() {
162         showView(ProgramSections.SUMMARY);
163     }
164 
165     @Override
166     protected void doSave() {
167         doSave(NO_OP_CALLBACK);
168     }
169 
170     private void doSave(final Callback<Boolean> okCallback) {
171         requestModel(new ModelRequestCallback<DataModel>() {
172             @Override
173             public void onModelReady(DataModel model) {
174                 CredentialEditController.this.updateModelFromCurrentView();
175                 model.validate(new Callback<List<ValidationResultInfo>>() {
176                     @Override
177                     public void exec(List<ValidationResultInfo> result) {
178                         boolean isSectionValid = isValid(result, true);
179                         if (isSectionValid) {
180                             saveData(okCallback);
181                         } else {
182                             okCallback.exec(false);
183                             KSNotifier.add(new KSNotification("Unable to save, please check fields for errors.", false, true, 5000));
184                         }
185                     }
186                 });
187 
188             }
189 
190             @Override
191             public void onRequestFail(Throwable cause) {
192                 GWT.log("Unable to retrieve model for validation and save", cause);
193             }
194         });
195     }
196 
197     private void saveData(final Callback<Boolean> okCallback) {
198         programRemoteService.saveData(programModel.getRoot(), new AbstractCallback<DataSaveResult>(getLabel(ProgramMsgConstants.COMMON_SAVINGDATA)) {
199             @Override
200             public void onSuccess(DataSaveResult result) {
201                 super.onSuccess(result);
202                 //Clear warning states on field and any warnings stored in ApplicationContext;
203                 clearAllWarnings();
204                 Application.getApplicationContext().clearValidationWarnings();
205                 
206                 List<ValidationResultInfo> validationResults = result.getValidationResults();
207                 Application.getApplicationContext().addValidationWarnings(validationResults);
208 
209                 if (ValidatorClientUtils.hasErrors(validationResults)) {
210                     isValid(result.getValidationResults(), false, true);
211                     StringBuilder msg = new StringBuilder();
212                     for (ValidationResultInfo vri : result.getValidationResults()) {
213                     	if(!msg.toString().contains(vri.getMessage()))
214                     		msg.append(vri.getMessage() + " ");
215                     }
216                     if (msg.length() > 0)
217                     	KSNotifier.add(new KSNotification(msg.toString(), false, true, 5000));
218                     okCallback.exec(false);
219                 } else {
220                     refreshModelAndView(result);
221                     resetFieldInteractionFlag();
222                     throwAfterSaveEvent();
223                     if (ProgramSections.getViewForUpdate().contains(getCurrentViewEnum().name())) {
224                         showView(getCurrentViewEnum());
225                     }
226                     HistoryManager.logHistoryChange();
227 
228                     if (ValidatorClientUtils.hasWarnings(validationResults)){
229 	    				isValid(result.getValidationResults(), false, true);	    				
230     					KSNotifier.show("Saved with Warnings");
231     				} else {
232                         KSNotifier.show(getLabel(ProgramMsgConstants.COMMON_SUCCESSFULSAVE));
233     				}  				
234 
235                     okCallback.exec(true);
236                 }
237             }
238         });
239     }
240 
241     @Override
242     protected void loadModel(ModelRequestCallback<DataModel> callback) {
243         ViewContext viewContext = getViewContext();
244         if (viewContext.getIdType() == IdType.COPY_OF_OBJECT_ID) {
245             createNewVersionAndLoadModel(callback, viewContext);
246         } else {
247             super.loadModel(callback);
248         }
249     }
250 
251     protected void createNewVersionAndLoadModel(final ModelRequestCallback<DataModel> callback, final ViewContext viewContext) {
252         Data data = new Data();
253         Data versionData = new Data();
254         versionData.set(new Data.StringKey("versionIndId"), getViewContext().getId());
255         versionData.set(new Data.StringKey("versionComment"), "Credential Program Version");
256         data.set(new Data.StringKey("versionInfo"), versionData);
257 
258         programRemoteService.saveData(data, new AbstractCallback<DataSaveResult>(getLabel(ProgramMsgConstants.COMMON_RETRIEVINGDATA)) {
259             @Override
260             public void onSuccess(DataSaveResult result) {
261                 super.onSuccess(result);
262                 programModel.setRoot(result.getValue());
263                 viewContext.setIdType(IdType.OBJECT_ID);
264                 viewContext.setId((String) programModel.get(ProgramConstants.ID));
265                 setHeaderTitle();
266                 setStatus();
267                 callback.onModelReady(programModel);
268                 eventBus.fireEvent(new ModelLoadedEvent(programModel));
269             }
270 
271             @Override
272             public void onFailure(Throwable caught) {
273                 super.onFailure(caught);
274                 callback.onRequestFail(caught);
275             }
276         });
277 
278     }
279 
280     private void throwAfterSaveEvent() {
281         eventBus.fireEvent(new AfterSaveEvent(programModel, this));
282     }
283 
284     @Override
285     public void onModelLoadedEvent() {
286         Enum<?> changeSection = ProgramRegistry.getSection();
287         if (changeSection != null) {
288             showView(changeSection);
289             ProgramRegistry.setSection(null);
290         } else {
291             String id = getStringProperty(ProgramConstants.ID);
292             if (id == null) {
293                 showView(ProgramSections.PROGRAM_DETAILS_EDIT);
294             } else {
295                 showView(ProgramSections.SUMMARY);
296             }
297         }
298     }
299     
300 	@Override
301 	public void beforeShow(final Callback<Boolean> onReadyCallback) {
302 		if(!initialized){
303 			Application.getApplicationContext().clearCrossConstraintMap(null);
304 			Application.getApplicationContext().clearPathToFieldMapping(null);
305 		}
306 		//Clear the parent path again
307 		Application.getApplicationContext().setParentPath("");
308 		super.beforeShow(onReadyCallback);
309 	}
310 	
311 	//Before show is called before the model is bound to the widgets. We need to update cross constraints after widget binding
312 	//This gets called twice which is not optimal
313 	@Override
314 	public <V extends Enum<?>> void showView(V viewType,
315 			final Callback<Boolean> onReadyCallback) {
316 		Callback<Boolean> updateCrossConstraintsCallback = new Callback<Boolean>(){
317 			public void exec(Boolean result) {
318 				onReadyCallback.exec(result);
319 		        for(HasCrossConstraints crossConstraint:Application.getApplicationContext().getCrossConstraints(null)){
320 		        	crossConstraint.reprocessWithUpdatedConstraints();
321 		        }
322 		        showWarnings();	
323 			}
324         };
325 		super.showView(viewType, updateCrossConstraintsCallback);
326 	}
327 }