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.ViewContext;
13 import org.kuali.student.common.ui.client.configurable.mvc.layouts.MenuSectionController;
14 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
15 import org.kuali.student.common.ui.client.configurable.mvc.views.SectionView;
16 import org.kuali.student.common.ui.client.mvc.Callback;
17 import org.kuali.student.common.ui.client.mvc.DataModel;
18 import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
19 import org.kuali.student.common.ui.client.mvc.ModelProvider;
20 import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
21 import org.kuali.student.common.ui.client.mvc.View;
22 import org.kuali.student.common.ui.client.mvc.dto.ReferenceModel;
23 import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
24 import org.kuali.student.common.ui.client.service.DataSaveResult;
25 import org.kuali.student.common.ui.client.util.ExportElement;
26 import org.kuali.student.common.ui.client.util.ExportUtils;
27 import org.kuali.student.common.ui.client.widgets.KSButton;
28 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract;
29 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations;
30 import org.kuali.student.common.ui.client.widgets.dialog.ButtonMessageDialog;
31 import org.kuali.student.common.ui.client.widgets.field.layout.button.ButtonGroup;
32 import org.kuali.student.common.ui.client.widgets.field.layout.button.YesNoCancelGroup;
33 import org.kuali.student.common.ui.shared.IdAttributes;
34 import org.kuali.student.common.ui.shared.IdAttributes.IdType;
35 import org.kuali.student.core.comments.ui.client.widgets.commenttool.CommentTool;
36 import org.kuali.student.lum.common.client.helpers.RecentlyViewedHelper;
37 import org.kuali.student.lum.common.client.widgets.AppLocations;
38 import org.kuali.student.lum.program.client.events.ModelLoadedEvent;
39 import org.kuali.student.lum.program.client.events.UpdateEvent;
40 import org.kuali.student.lum.program.client.properties.ProgramProperties;
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 private 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.show();
139 } else {
140 okToChange.exec(true);
141 }
142 } else {
143 okToChange.exec(false);
144 }
145 }
146 });
147 } else {
148 processBeforeShow = true;
149 }
150 }
151
152 protected void fireUpdateEvent(final Callback<Boolean> okToChange) {
153 eventBus.fireEvent(new UpdateEvent(okToChange));
154 }
155
156 protected void resetModel() {
157 programModel.resetRoot();
158 }
159
160 protected void resetFieldInteractionFlag() {
161 View currentView = getCurrentView();
162 if (currentView instanceof Section) {
163 ((Section) currentView).resetFieldInteractionFlags();
164 }
165 }
166
167
168
169
170 private void initializeModel() {
171 setDefaultModelId(ProgramConstants.PROGRAM_MODEL_ID);
172 registerModel(ProgramConstants.PROGRAM_MODEL_ID, new ModelProvider<DataModel>() {
173 @Override
174 public void requestModel(final ModelRequestCallback<DataModel> callback) {
175 if (programModel.getRoot() == null || programModel.getRoot().size() == 0) {
176 loadModel(callback);
177 } else {
178 callback.onModelReady(programModel);
179 }
180 }
181 });
182 }
183
184
185 @Override
186 public void requestModel(Class modelType, ModelRequestCallback callback) {
187 if (modelType == ReferenceModel.class) {
188 ReferenceModel referenceModel = new ReferenceModel();
189 referenceModel.setReferenceId(ProgramUtils.getProgramId(programModel));
190 referenceModel.setReferenceTypeKey(ProgramConstants.MAJOR_REFERENCE_TYPE_ID);
191 referenceModel.setReferenceType(ProgramConstants.MAJOR_LU_TYPE_ID);
192 Map<String, String> attributes = new HashMap<String, String>();
193 attributes.put("name", getStringProperty("name"));
194 referenceModel.setReferenceAttributes(attributes);
195 callback.onModelReady(referenceModel);
196 } else {
197 super.requestModel(modelType, callback);
198 }
199 }
200
201
202
203
204
205
206
207 protected void loadModel(final ModelRequestCallback<DataModel> callback) {
208 programRemoteService.getData(getViewContext().getId(), new AbstractCallback<Data>(ProgramProperties.get().common_retrievingData()) {
209
210 @Override
211 public void onFailure(Throwable caught) {
212 super.onFailure(caught);
213 callback.onRequestFail(caught);
214 }
215
216 @Override
217 public void onSuccess(Data result) {
218 super.onSuccess(result);
219 programModel.setRoot(result);
220 setHeaderTitle();
221 callback.onModelReady(programModel);
222 }
223 });
224 }
225
226 private void setModelData() {
227 setHeaderTitle();
228 setStatus();
229 configurer.applyPermissions();
230
231 if (needToLoadOldModel) {
232 needToLoadOldModel = false;
233 } else {
234 String id = ProgramUtils.getProgramId(programModel);
235 if (null != id) {
236
237 ViewContext docContext = new ViewContext();
238 docContext.setId(id);
239 docContext.setIdType(IdType.OBJECT_ID);
240 String pgmType = getStringProperty(ProgramConstants.TYPE);
241 docContext.setAttribute(ProgramConstants.TYPE, pgmType + '/' + ProgramSections.PROGRAM_DETAILS_VIEW);
242 RecentlyViewedHelper.addDocument(getProgramName(),
243 HistoryManager.appendContext(getProgramViewLocation(pgmType), docContext));
244 }
245 eventBus.fireEvent(new ModelLoadedEvent(programModel));
246 onModelLoadedEvent();
247 }
248 }
249
250 private String getProgramViewLocation(String pgmType) {
251 if (ProgramClientConstants.MAJOR_PROGRAM.equals(pgmType)) {
252 return AppLocations.Locations.VIEW_PROGRAM.getLocation();
253 } else if (ProgramClientConstants.CORE_PROGRAM.equals(pgmType)) {
254 return AppLocations.Locations.VIEW_CORE_PROGRAM.getLocation();
255 } else if (ProgramClientConstants.CREDENTIAL_PROGRAM_TYPES.contains(pgmType)) {
256 return AppLocations.Locations.VIEW_BACC_PROGRAM.getLocation();
257 }
258 return null;
259 }
260
261 protected void setStatus() {
262 statusLabel.setText(ProgramProperties.get().common_status(getStringProperty(ProgramConstants.STATE)));
263 }
264
265 public String getProgramName() {
266 String name = getStringProperty(ProgramConstants.LONG_TITLE);
267 if (name == null) {
268 name = ProgramProperties.get().common_newProgram();
269 }
270 return name;
271 }
272
273
274
275
276
277
278 @Override
279 public void beforeShow(final Callback<Boolean> onReadyCallback) {
280 if (programModel.getRoot() == null) {
281 loadModel(new ModelRequestCallback<DataModel>() {
282 @Override
283 public void onModelReady(DataModel model) {
284 if (loadMetadataCondition()) {
285 loadMetadata(onReadyCallback);
286 } else {
287
288 onReadyCallback.exec(true);
289 }
290 }
291
292 @Override
293 public void onRequestFail(Throwable cause) {
294 GWT.log(cause.getMessage());
295 }
296 });
297 } else {
298 afterMetadataLoaded(onReadyCallback);
299 }
300 }
301
302
303
304
305
306
307 protected boolean loadMetadataCondition() {
308 return lastLoadedStatus == null || ProgramStatus.of(programModel) != lastLoadedStatus;
309 }
310
311
312
313
314
315
316 protected void loadMetadata(final Callback<Boolean> onReadyCallback) {
317 Map<String, String> idAttributes = new HashMap<String, String>();
318 ViewContext viewContext = getViewContext();
319 IdType idType = viewContext.getIdType();
320 String viewContextId = null;
321 if (idType != null) {
322 idAttributes.put(IdAttributes.ID_TYPE, idType.toString());
323 viewContextId = viewContext.getId();
324 if (idType == IdType.COPY_OF_OBJECT_ID) {
325 viewContextId = null;
326 }
327 }
328 if (programModel.getRoot() != null) {
329 ProgramStatus programStatus = ProgramStatus.of(programModel);
330 idAttributes.put(DtoConstants.DTO_STATE, programStatus.getValue());
331 if (programStatus.getNextStatus() != null) {
332 idAttributes.put(DtoConstants.DTO_NEXT_STATE, programStatus.getNextStatus().getValue());
333 }
334 }
335 programRemoteService.getMetadata(viewContextId, idAttributes, new AbstractCallback<Metadata>() {
336
337 @Override
338 public void onSuccess(Metadata result) {
339 super.onSuccess(result);
340 DataModelDefinition def = new DataModelDefinition(result);
341 programModel.setDefinition(def);
342 lastLoadedStatus = ProgramStatus.of(programModel);
343 afterMetadataLoaded(onReadyCallback);
344 }
345
346 @Override
347 public void onFailure(Throwable caught) {
348 super.onFailure(caught);
349 onReadyCallback.exec(false);
350 }
351 });
352 }
353
354 protected void configureView() {
355 addStyleName("programController");
356 configurer.setModelDefinition(programModel.getDefinition());
357 configurer.configure(this);
358 addContentWidget(statusLabel);
359 setSideBarWidget(sideBar);
360 }
361
362 @Override
363 public void setViewContext(ViewContext viewContext) {
364 super.setViewContext(viewContext);
365 if (viewContext.getId() != null && !viewContext.getId().isEmpty()) {
366 viewContext.setPermissionType(PermissionType.OPEN);
367 } else {
368 viewContext.setPermissionType(PermissionType.INITIATE);
369 }
370 }
371
372
373
374
375
376
377 protected void afterMetadataLoaded(Callback<Boolean> onReadyCallback) {
378 if (!reloadMetadata) {
379 configureView();
380 onReadyCallback.exec(true);
381 reloadMetadata = true;
382 } else {
383 onReadyCallback.exec(true);
384 ProgramUtils.syncMetadata(configurer, programModel.getDefinition());
385 }
386 if (programModel.getRoot() != null) {
387 setModelData();
388 }
389 }
390
391 protected void setHeaderTitle() {
392 String title = getProgramName();
393 this.setContentTitle(title);
394 this.setName(title);
395 }
396
397 protected Widget createCommentPanel() {
398 final CommentTool commentTool = new CommentTool(ProgramSections.COMMENTS, "Comments", "kuali.comment.type.generalRemarks", "Program Comments");
399 commentTool.setController(this);
400 KSButton commentsButton = new KSButton(ProgramProperties.get().comments_button(), KSButtonAbstract.ButtonStyle.DEFAULT_ANCHOR, new ClickHandler() {
401
402 @Override
403 public void onClick(ClickEvent event) {
404 commentTool.show();
405 }
406 });
407 return commentsButton;
408 }
409
410 protected void doSave() {
411 }
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437 protected void updateState(String state, final Callback<Boolean> okCallback) {
438
439 programRemoteService.updateState(programModel.getRoot(), state, new AbstractCallback<DataSaveResult>(ProgramProperties.get().common_savingData()) {
440 @Override
441 public void onSuccess(DataSaveResult result) {
442 super.onSuccess(result);
443 okCallback.exec(true);
444 refreshModelAndView(result);
445 }
446 });
447
448 }
449
450
451
452
453
454 public void refreshModelAndView(DataSaveResult result){
455 if (result != null) {
456 programModel.setRoot(result.getValue());
457 }
458 setHeaderTitle();
459 setStatus();
460 }
461
462 public DataModel getProgramModel() {
463 return programModel;
464 }
465
466 public void onModelLoadedEvent() {
467 }
468
469 protected String getStringProperty(String key) {
470 return programModel.get(key);
471 }
472
473 protected Data getDataProperty(String key) {
474 return programModel.get(key);
475 }
476
477 public boolean isExportButtonActive() {
478 if (this.getCurrentViewEnum() != null) {
479 if (this.getCurrentViewEnum().equals(ProgramSections.SUMMARY)
480 || this.getCurrentViewEnum().equals(ProgramSections.VIEW_ALL)) {
481 return true;
482 } else {
483 return false;
484 }
485
486 } else {
487 return false;
488 }
489 }
490
491 @Override
492 public ArrayList<ExportElement> getExportElementsFromView() {
493
494 String viewName = null;
495 String sectionTitle = null;
496 View currentView = this.getCurrentView();
497 if (currentView != null) {
498
499 ArrayList<ExportElement> exportElements = new ArrayList<ExportElement>();
500 if (currentView != null && currentView instanceof Section) {
501 Section currentSection = (Section) currentView;
502 List<Section> nestedSections = currentSection.getSections();
503 for (int i = 0; i < nestedSections.size(); i++) {
504 ExportElement sectionExportItem = new ExportElement();
505 ArrayList<ExportElement> subList = null;
506 Section nestedSection = nestedSections.get(i);
507 if (nestedSection != null && nestedSection instanceof SectionView) {
508 SectionView nestedSectionView = (SectionView) nestedSection;
509 viewName = nestedSectionView.getName();
510 sectionTitle = nestedSectionView.getTitle();
511 sectionExportItem.setSectionName(sectionTitle + " " + i + " - " + viewName);
512 sectionExportItem.setViewName(sectionTitle + " " + i + " - " + viewName);
513 subList = ExportUtils.getExportElementsFromView(nestedSectionView, subList, viewName, sectionTitle);
514 if (subList != null && subList.size()> 0) {
515 sectionExportItem.setSubset(subList);
516 exportElements.add(sectionExportItem);
517 }
518 }
519 }
520 }
521 return exportElements;
522
523 } else {
524
525 }
526 return null;
527
528 }
529 }