1 package org.kuali.student.lum.program.client;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import org.kuali.student.common.assembly.data.Data;
9 import org.kuali.student.common.assembly.data.Metadata;
10 import org.kuali.student.common.dto.DtoConstants;
11 import org.kuali.student.common.rice.authorization.PermissionType;
12 import org.kuali.student.common.ui.client.application.Application;
13 import org.kuali.student.common.ui.client.application.ViewContext;
14 import org.kuali.student.common.ui.client.configurable.mvc.layouts.MenuSectionController;
15 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
16 import org.kuali.student.common.ui.client.configurable.mvc.views.SectionView;
17 import org.kuali.student.common.ui.client.mvc.Callback;
18 import org.kuali.student.common.ui.client.mvc.DataModel;
19 import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
20 import org.kuali.student.common.ui.client.mvc.ModelProvider;
21 import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
22 import org.kuali.student.common.ui.client.mvc.View;
23 import org.kuali.student.common.ui.client.mvc.dto.ReferenceModel;
24 import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
25 import org.kuali.student.common.ui.client.service.DataSaveResult;
26 import org.kuali.student.common.ui.client.util.ExportElement;
27 import org.kuali.student.common.ui.client.util.ExportUtils;
28 import org.kuali.student.common.ui.client.widgets.KSButton;
29 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract;
30 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations;
31 import org.kuali.student.common.ui.client.widgets.dialog.ButtonMessageDialog;
32 import org.kuali.student.common.ui.client.widgets.field.layout.button.ButtonGroup;
33 import org.kuali.student.common.ui.client.widgets.field.layout.button.YesNoCancelGroup;
34 import org.kuali.student.common.ui.shared.IdAttributes;
35 import org.kuali.student.common.ui.shared.IdAttributes.IdType;
36 import org.kuali.student.core.comments.ui.client.widgets.commenttool.CommentTool;
37 import org.kuali.student.lum.common.client.helpers.RecentlyViewedHelper;
38 import org.kuali.student.lum.common.client.widgets.AppLocations;
39 import org.kuali.student.lum.program.client.events.ModelLoadedEvent;
40 import org.kuali.student.lum.program.client.events.UpdateEvent;
41 import org.kuali.student.lum.program.client.rpc.AbstractCallback;
42 import org.kuali.student.lum.program.client.rpc.MajorDisciplineRpcService;
43 import org.kuali.student.lum.program.client.rpc.MajorDisciplineRpcServiceAsync;
44 import org.kuali.student.lum.program.client.widgets.ProgramSideBar;
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.event.shared.HandlerManager;
50 import com.google.gwt.user.client.ui.Label;
51 import com.google.gwt.user.client.ui.Widget;
52
53
54
55
56 public abstract class ProgramController extends MenuSectionController {
57
58 protected MajorDisciplineRpcServiceAsync programRemoteService;
59
60 protected boolean initialized = false;
61
62 protected DataModel programModel;
63
64 protected AbstractProgramConfigurer configurer;
65
66 protected HandlerManager eventBus;
67
68 protected Label statusLabel = new Label();
69
70 protected ProgramSideBar sideBar;
71
72 private boolean needToLoadOldModel = false;
73
74 protected ProgramStatus lastLoadedStatus;
75
76 protected boolean reloadMetadata = false;
77
78 protected boolean processBeforeShow = true;
79
80
81
82
83
84
85 public ProgramController(String name, DataModel programModel, ViewContext viewContext, HandlerManager eventBus) {
86 super();
87 programRemoteService = createProgramRemoteService();
88 this.eventBus = eventBus;
89 this.programModel = programModel;
90 setViewContext(viewContext);
91 initializeModel();
92 }
93
94
95
96
97
98 protected MajorDisciplineRpcServiceAsync createProgramRemoteService() {
99 return GWT.create(MajorDisciplineRpcService.class);
100 }
101
102 @Override
103 public void beforeViewChange(Enum<?> viewChangingTo, final Callback<Boolean> okToChange) {
104 if (processBeforeShow) {
105 super.beforeViewChange(viewChangingTo, new Callback<Boolean>() {
106
107 @Override
108 public void exec(Boolean result) {
109 if (result) {
110 if (getCurrentView() instanceof SectionView && ((SectionView) getCurrentView()).isDirty()) {
111 ButtonGroup<ButtonEnumerations.YesNoCancelEnum> buttonGroup = new YesNoCancelGroup();
112 final ButtonMessageDialog<ButtonEnumerations.YesNoCancelEnum> dialog = new ButtonMessageDialog<ButtonEnumerations.YesNoCancelEnum>("Warning", "You may have unsaved changes. Save changes?", buttonGroup);
113 buttonGroup.addCallback(new Callback<ButtonEnumerations.YesNoCancelEnum>() {
114
115 @Override
116 public void exec(ButtonEnumerations.YesNoCancelEnum result) {
117 switch (result) {
118 case YES:
119 dialog.hide();
120 fireUpdateEvent(okToChange);
121 break;
122 case NO:
123 dialog.hide();
124 resetModel();
125 needToLoadOldModel = true;
126 resetFieldInteractionFlag();
127 okToChange.exec(true);
128 break;
129 case CANCEL:
130 okToChange.exec(false);
131 dialog.hide();
132
133 HistoryManager.logHistoryChange();
134 break;
135 }
136 }
137 });
138 dialog.addCloseLinkClickHandler(new ClickHandler() {
139
140 @Override
141 public void onClick(ClickEvent event) {
142 okToChange.exec(false);
143 dialog.hide();
144
145 HistoryManager.logHistoryChange();
146 }
147 });
148 dialog.show();
149 } else {
150 okToChange.exec(true);
151 }
152 } else {
153 okToChange.exec(false);
154 }
155 }
156 });
157 } else {
158 processBeforeShow = true;
159 }
160 }
161
162 protected void fireUpdateEvent(final Callback<Boolean> okToChange) {
163 eventBus.fireEvent(new UpdateEvent(okToChange));
164 }
165
166 protected void resetModel() {
167 programModel.resetRoot();
168 }
169
170 protected void resetFieldInteractionFlag() {
171 View currentView = getCurrentView();
172 if (currentView instanceof Section) {
173 ((Section) currentView).resetFieldInteractionFlags();
174 }
175 }
176
177
178
179
180 private void initializeModel() {
181 setDefaultModelId(ProgramConstants.PROGRAM_MODEL_ID);
182 registerModel(ProgramConstants.PROGRAM_MODEL_ID, new ModelProvider<DataModel>() {
183 @Override
184 public void requestModel(final ModelRequestCallback<DataModel> callback) {
185 if (programModel.getRoot() == null || programModel.getRoot().size() == 0) {
186 loadModel(callback);
187 } else {
188 callback.onModelReady(programModel);
189 }
190 }
191 });
192 }
193
194
195 @Override
196 public void requestModel(Class modelType, ModelRequestCallback callback) {
197 if (modelType == ReferenceModel.class) {
198 ReferenceModel referenceModel = new ReferenceModel();
199 referenceModel.setReferenceId(ProgramUtils.getProgramId(programModel));
200 referenceModel.setReferenceTypeKey(ProgramConstants.MAJOR_REFERENCE_TYPE_ID);
201 referenceModel.setReferenceType(ProgramConstants.MAJOR_LU_TYPE_ID);
202 Map<String, String> attributes = new HashMap<String, String>();
203 attributes.put("name", getStringProperty("name"));
204 referenceModel.setReferenceAttributes(attributes);
205 callback.onModelReady(referenceModel);
206 } else {
207 super.requestModel(modelType, callback);
208 }
209 }
210
211
212
213
214
215
216
217 protected void loadModel(final ModelRequestCallback<DataModel> callback) {
218 programRemoteService.getData(getViewContext().getId(), new AbstractCallback<Data>(getLabel(ProgramMsgConstants.COMMON_RETRIEVINGDATA)) {
219
220 @Override
221 public void onFailure(Throwable caught) {
222 super.onFailure(caught);
223 callback.onRequestFail(caught);
224 }
225
226 @Override
227 public void onSuccess(Data result) {
228 super.onSuccess(result);
229 programModel.setRoot(result);
230 setHeaderTitle();
231 callback.onModelReady(programModel);
232 }
233 });
234 }
235
236 private void setModelData() {
237 setHeaderTitle();
238 setStatus();
239 configurer.applyPermissions();
240
241 if (needToLoadOldModel) {
242 needToLoadOldModel = false;
243 } else {
244 String id = ProgramUtils.getProgramId(programModel);
245 if (null != id) {
246
247 ViewContext docContext = new ViewContext();
248 docContext.setId(id);
249 docContext.setIdType(IdType.OBJECT_ID);
250 String pgmType = getStringProperty(ProgramConstants.TYPE);
251 docContext.setAttribute(ProgramConstants.TYPE, pgmType + '/' + ProgramSections.PROGRAM_DETAILS_VIEW);
252 RecentlyViewedHelper.addDocument(getProgramName(),
253 HistoryManager.appendContext(getProgramViewLocation(pgmType), docContext));
254 }
255 eventBus.fireEvent(new ModelLoadedEvent(programModel));
256 onModelLoadedEvent();
257 }
258 }
259
260 private String getProgramViewLocation(String pgmType) {
261 if (ProgramClientConstants.MAJOR_PROGRAM.equals(pgmType)) {
262 return AppLocations.Locations.VIEW_PROGRAM.getLocation();
263 } else if (ProgramClientConstants.CORE_PROGRAM.equals(pgmType)) {
264 return AppLocations.Locations.VIEW_CORE_PROGRAM.getLocation();
265 } else if (ProgramClientConstants.CREDENTIAL_PROGRAM_TYPES.contains(pgmType)) {
266 return AppLocations.Locations.VIEW_BACC_PROGRAM.getLocation();
267 }
268 return null;
269 }
270
271 protected void setStatus() {
272 statusLabel.setText(getLabel(ProgramMsgConstants.COMMON_STATUS,getStringProperty(ProgramConstants.STATE)));
273 }
274
275 public String getProgramName() {
276 String name = getStringProperty(ProgramConstants.LONG_TITLE);
277 if (name == null) {
278 name = getLabel(ProgramMsgConstants.COMMON_NEWPROGRAM);
279 }
280 return name;
281 }
282
283
284
285
286
287
288 @Override
289 public void beforeShow(final Callback<Boolean> onReadyCallback) {
290 if (programModel.getRoot() == null) {
291 loadModel(new ModelRequestCallback<DataModel>() {
292 @Override
293 public void onModelReady(DataModel model) {
294 if (loadMetadataCondition()) {
295 loadMetadata(onReadyCallback);
296 } else {
297
298 onReadyCallback.exec(true);
299 }
300 }
301
302 @Override
303 public void onRequestFail(Throwable cause) {
304 GWT.log(cause.getMessage());
305 }
306 });
307 } else {
308 afterMetadataLoaded(onReadyCallback);
309 }
310 }
311
312
313
314
315
316
317 protected boolean loadMetadataCondition() {
318 return lastLoadedStatus == null || ProgramStatus.of(programModel) != lastLoadedStatus;
319 }
320
321
322
323
324
325
326 protected void loadMetadata(final Callback<Boolean> onReadyCallback) {
327 Map<String, String> idAttributes = new HashMap<String, String>();
328 ViewContext viewContext = getViewContext();
329 IdType idType = viewContext.getIdType();
330 String viewContextId = null;
331 if (idType != null) {
332 idAttributes.put(IdAttributes.ID_TYPE, idType.toString());
333 viewContextId = viewContext.getId();
334 if (idType == IdType.COPY_OF_OBJECT_ID) {
335
336 viewContextId = null;
337 }
338 }
339 if (programModel.getRoot() != null) {
340 ProgramStatus programStatus = ProgramStatus.of(programModel);
341 idAttributes.put(DtoConstants.DTO_STATE, programStatus.getValue());
342 if (programStatus.getNextStatus() != null) {
343 idAttributes.put(DtoConstants.DTO_NEXT_STATE, programStatus.getNextStatus().getValue());
344 }
345 }
346 programRemoteService.getMetadata(viewContextId, idAttributes, new AbstractCallback<Metadata>() {
347
348 @Override
349 public void onSuccess(Metadata result) {
350 super.onSuccess(result);
351 DataModelDefinition def = new DataModelDefinition(result);
352 programModel.setDefinition(def);
353 lastLoadedStatus = ProgramStatus.of(programModel);
354 afterMetadataLoaded(onReadyCallback);
355 }
356
357 @Override
358 public void onFailure(Throwable caught) {
359 super.onFailure(caught);
360 onReadyCallback.exec(false);
361 }
362 });
363 }
364
365 protected void configureView() {
366 addStyleName("programController");
367 configurer.setModelDefinition(programModel.getDefinition());
368 configurer.configure(this);
369 addContentWidget(statusLabel);
370 setSideBarWidget(sideBar);
371 }
372
373 @Override
374 public void setViewContext(ViewContext viewContext) {
375 super.setViewContext(viewContext);
376 if (viewContext.getId() != null && !viewContext.getId().isEmpty()) {
377 viewContext.setPermissionType(PermissionType.OPEN);
378 } else {
379 viewContext.setPermissionType(PermissionType.INITIATE);
380 }
381 }
382
383
384
385
386
387
388 protected void afterMetadataLoaded(Callback<Boolean> onReadyCallback) {
389 if (!reloadMetadata) {
390 configureView();
391 onReadyCallback.exec(true);
392 reloadMetadata = true;
393 } else {
394 onReadyCallback.exec(true);
395 ProgramUtils.syncMetadata(configurer, programModel.getDefinition());
396 }
397 if (programModel.getRoot() != null) {
398 setModelData();
399 }
400 }
401
402 protected void setHeaderTitle() {
403 String title = getProgramName();
404 this.setContentTitle(title);
405 this.setName(title);
406 }
407
408 protected Widget createCommentPanel() {
409 final CommentTool commentTool = new CommentTool(ProgramSections.COMMENTS, "Comments", "kuali.comment.type.generalRemarks", "Program Comments");
410 commentTool.setController(this);
411 KSButton commentsButton = new KSButton(getLabel(ProgramMsgConstants.COMMENTS_BUTTON), KSButtonAbstract.ButtonStyle.DEFAULT_ANCHOR, new ClickHandler() {
412
413 @Override
414 public void onClick(ClickEvent event) {
415 commentTool.show();
416 }
417 });
418 return commentsButton;
419 }
420
421 protected void doSave() {
422 }
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448 protected void updateState(String state, final Callback<Boolean> okCallback) {
449
450 programRemoteService.updateState(programModel.getRoot(), state, new AbstractCallback<DataSaveResult>(getLabel(ProgramMsgConstants.COMMON_SAVINGDATA)) {
451 @Override
452 public void onSuccess(DataSaveResult result) {
453 if(result.getValidationResults()==null || result.getValidationResults().isEmpty()){
454 super.onSuccess(result);
455 okCallback.exec(true);
456 refreshModelAndView(result);
457 }else{
458
459 super.onSuccess(result);
460
461 isValid(result.getValidationResults(), false, true);
462 ProgramUtils.handleValidationErrorsForSpecializations(result.getValidationResults(), programModel);
463
464 okCallback.exec(false);
465 }
466 }
467
468 });
469
470 }
471
472
473
474
475
476 public void refreshModelAndView(DataSaveResult result){
477 if (result != null) {
478 programModel.setRoot(result.getValue());
479 }
480 setHeaderTitle();
481 setStatus();
482 }
483
484 public DataModel getProgramModel() {
485 return programModel;
486 }
487
488 public void onModelLoadedEvent() {
489 }
490
491 protected String getStringProperty(String key) {
492 return programModel.get(key);
493 }
494
495 protected Data getDataProperty(String key) {
496 return programModel.get(key);
497 }
498
499 public boolean isExportButtonActive() {
500 if (this.getCurrentViewEnum() != null) {
501 if (this.getCurrentViewEnum().equals(ProgramSections.SUMMARY)
502 || this.getCurrentViewEnum().equals(ProgramSections.VIEW_ALL)) {
503 return true;
504 } else {
505 return false;
506 }
507
508 } else {
509 return false;
510 }
511 }
512
513
514
515
516
517 @Override
518 public String getExportTemplateName() {
519 if (this.getCurrentViewEnum().equals(ProgramSections.VIEW_ALL)){
520 return "base.template";
521 }
522 return "proposal.template";
523 }
524
525 @Override
526 public List<ExportElement> getExportElementsFromView() {
527
528 String viewName = null;
529 String sectionTitle = null;
530 View currentView = this.getCurrentView();
531 if (currentView != null) {
532
533 List<ExportElement> exportElements = new ArrayList<ExportElement>();
534 ExportElement heading = new ExportElement();
535 heading.setFieldLabel("");
536 heading.setFieldValue(currentView.getName());
537 exportElements.add(heading);
538
539 if (currentView instanceof Section) {
540 Section currentSection = (Section) currentView;
541 List<Section> nestedSections = currentSection.getSections();
542 for (int i = 0; i < nestedSections.size(); i++) {
543 ExportElement sectionExportItem = new ExportElement();
544 ArrayList<ExportElement> subList = null;
545 Section nestedSection = nestedSections.get(i);
546 if (nestedSection != null && nestedSection instanceof SectionView) {
547 SectionView nestedSectionView = (SectionView) nestedSection;
548 viewName = nestedSectionView.getName();
549 sectionTitle = nestedSectionView.getTitle();
550 sectionExportItem.setSectionName(sectionTitle + " " + i + " - " + viewName);
551 sectionExportItem.setViewName(sectionTitle + " " + i + " - " + viewName);
552 subList = ExportUtils.getExportElementsFromView(nestedSectionView, subList, viewName, sectionTitle);
553 if (subList != null && subList.size()> 0) {
554 sectionExportItem.setSubset(subList);
555 exportElements.add(sectionExportItem);
556 }
557 }
558 }
559 }
560 return exportElements;
561
562 } else {
563
564 }
565 return null;
566
567 }
568
569 protected String getLabel(String messageKey) {
570 return Application.getApplicationContext().getUILabel(ProgramMsgConstants.PROGRAM_MSG_GROUP, messageKey);
571 }
572
573 protected String getLabel(String messageKey, String parameter) {
574 Map<String, Object> parameters = new HashMap<String, Object>();
575 parameters.put("0", parameter);
576 return Application.getApplicationContext().getUILabel(ProgramMsgConstants.PROGRAM_MSG_GROUP, messageKey, parameters);
577 }
578
579 }