1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.common.ui.client.configurable.mvc;
17
18 import java.util.HashMap;
19 import java.util.LinkedHashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Map.Entry;
23
24 import org.kuali.student.common.ui.client.configurable.mvc.layouts.ViewLayoutController;
25 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
26 import org.kuali.student.common.ui.client.configurable.mvc.views.SectionView;
27 import org.kuali.student.common.ui.client.event.ActionEvent;
28 import org.kuali.student.common.ui.client.event.SaveActionEvent;
29 import org.kuali.student.common.ui.client.event.SectionUpdateEvent;
30 import org.kuali.student.common.ui.client.event.SectionUpdateHandler;
31 import org.kuali.student.common.ui.client.event.ValidateRequestEvent;
32 import org.kuali.student.common.ui.client.event.ValidateRequestHandler;
33 import org.kuali.student.common.ui.client.mvc.ActionCompleteCallback;
34 import org.kuali.student.common.ui.client.mvc.Callback;
35 import org.kuali.student.common.ui.client.mvc.Controller;
36 import org.kuali.student.common.ui.client.mvc.DataModel;
37 import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
38 import org.kuali.student.common.ui.client.mvc.View;
39 import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
40 import org.kuali.student.common.ui.client.widgets.KSButton;
41 import org.kuali.student.common.ui.client.widgets.KSLightBox;
42 import org.kuali.student.common.ui.client.widgets.field.layout.element.FieldElement;
43 import org.kuali.student.core.validation.dto.ValidationResultInfo;
44 import org.kuali.student.core.validation.dto.ValidationResultInfo.ErrorLevel;
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.user.client.ui.FlowPanel;
50 import com.google.gwt.user.client.ui.Widget;
51
52 public abstract class LayoutController extends Controller implements ViewLayoutController, View {
53
54 protected Map<Enum<?>, View> viewMap = new LinkedHashMap<Enum<?>, View>();
55 protected Map<String, Enum<?>> viewEnumMap = new HashMap<String, Enum<?>>();
56 protected Enum<?> defaultView;
57
58 protected String name;
59 protected Enum<?> viewType;
60
61 protected View startPopupView;
62 protected KSLightBox startViewWindow;
63
64 public LayoutController(String controllerId){
65 super(controllerId);
66
67 addApplicationEventHandler(SectionUpdateEvent.TYPE, new SectionUpdateHandler(){
68
69 @Override
70 public void onSectionUpdate(final SectionUpdateEvent event) {
71 LayoutController.this.requestModel(new ModelRequestCallback<DataModel>(){
72
73 @Override
74 public void onRequestFail(Throwable cause) {
75 GWT.log("Unable to retrieve model for section update", cause);
76 }
77
78 @Override
79 public void onModelReady(DataModel model) {
80 event.getSection().updateModel(model);
81 event.getSection().updateWidgetData(model);
82
83 }
84 });
85
86 }
87 });
88
89 addApplicationEventHandler(ValidateRequestEvent.TYPE, new ValidateRequestHandler() {
90
91 @Override
92 public void onValidateRequest(final ValidateRequestEvent event) {
93 FieldDescriptor originatingField = event.getFieldDescriptor();
94 String modelId = null;
95 if (originatingField != null) {
96 modelId = originatingField.getModelId();
97 }
98 if (modelId == null) {
99 requestModel(new ModelRequestCallback<DataModel>() {
100 @Override
101 public void onModelReady(DataModel model) {
102 validate(model, event);
103 }
104
105 @Override
106 public void onRequestFail(Throwable cause) {
107 GWT.log("Unable to retrieve model for validation", cause);
108 }
109
110 });
111 } else {
112 requestModel(modelId, new ModelRequestCallback<DataModel>() {
113 @Override
114 public void onModelReady(DataModel model) {
115 validate(model, event);
116 }
117
118 @Override
119 public void onRequestFail(Throwable cause) {
120 GWT.log("Unable to retrieve model for validation", cause);
121 }
122
123 });
124 }
125 }
126
127 });
128 }
129
130 private void validate(DataModel model, final ValidateRequestEvent event) {
131 if(event.validateSingleField()){
132 model.validateField(event.getFieldDescriptor(), new Callback<List<ValidationResultInfo>>() {
133 @Override
134 public void exec(List<ValidationResultInfo> result) {
135 if(event.getFieldDescriptor() != null){
136
137
138 FieldElement element = event.getFieldDescriptor().getFieldElement();
139 if(element != null){
140 element.clearValidationPanel();
141 for(int i = 0; i < result.size(); i++){
142 ValidationResultInfo vr = result.get(i);
143 if(vr.getElement().equals(event.getFieldDescriptor().getFieldKey())
144 && event.getFieldDescriptor().hasHadFocus()){
145 element.processValidationResult(vr);
146 }
147 }
148 }
149 }
150
151 }
152 });
153 }
154 else{
155 model.validate(new Callback<List<ValidationResultInfo>>() {
156 @Override
157 public void exec(List<ValidationResultInfo> result) {
158 isValid(result, false, true);
159 }
160 });
161 }
162 }
163
164 public ErrorLevel checkForErrors(List<ValidationResultInfo> list){
165 ErrorLevel errorLevel = ErrorLevel.OK;
166
167 for(ValidationResultInfo vr: list){
168 if(vr.getErrorLevel().getLevel() > errorLevel.getLevel()){
169 errorLevel = vr.getErrorLevel();
170 }
171 if(errorLevel.equals(ErrorLevel.ERROR)){
172 break;
173 }
174 }
175
176 return errorLevel;
177
178 }
179
180 public static LayoutController findParentLayout(Widget w){
181 LayoutController result = null;
182 while (true) {
183 if (w == null) {
184 break;
185 } else if (w instanceof HasLayoutController) {
186 result = ((HasLayoutController)w).getLayoutController();
187 if (result != null) {
188 break;
189 }
190 } else if (w instanceof LayoutController) {
191 result = (LayoutController) w;
192 break;
193 }
194 w = w.getParent();
195
196 }
197 return result;
198 }
199
200 public void addStartViewPopup(final View view){
201 startPopupView = view;
202 if(startViewWindow == null){
203 startViewWindow = new KSLightBox();
204 }
205
206 FlowPanel panel = new FlowPanel();
207 panel.add(view.asWidget());
208 KSButton save = new KSButton("Save",new ClickHandler(){
209 public void onClick(ClickEvent event) {
210 view.updateModel();
211 SaveActionEvent saveActionEvent = new SaveActionEvent(true);
212
213 saveActionEvent.setActionCompleteCallback(new ActionCompleteCallback(){
214 public void onActionComplete(ActionEvent action) {
215 startViewWindow.hide();
216 }
217 });
218
219
220 fireApplicationEvent(saveActionEvent);
221 }
222 });
223 startViewWindow.addButton(save);
224
225 KSButton cancel = new KSButton("Cancel", new ClickHandler(){
226 public void onClick(ClickEvent event) {
227 startViewWindow.hide();
228 }
229 });
230 startViewWindow.addButton(cancel);
231
232 if(view instanceof SectionView){
233 ((SectionView) view).setController(this);
234 }
235 startViewWindow.setWidget(panel);
236 }
237
238 public boolean isStartViewShowing(){
239 if(startViewWindow == null){
240 return false;
241 }
242 return startViewWindow.isShowing();
243 }
244
245 public View getStartPopupView(){
246 return startPopupView;
247 }
248
249 public void showStartPopup(final Callback<Boolean> onReadyCallback){
250 startPopupView.beforeShow(new Callback<Boolean>() {
251 @Override
252 public void exec(Boolean result) {
253 if (result) {
254 startViewWindow.show();
255 }
256 onReadyCallback.exec(result);
257 }
258 });
259 }
260
261 public KSLightBox getStartPopup(){
262 return startViewWindow;
263 }
264
265
266
267
268 public void addView(View view){
269 viewMap.put(view.getViewEnum(), view);
270 viewEnumMap.put(view.getViewEnum().toString(), view.getViewEnum());
271 if(view instanceof SectionView){
272 ((SectionView) view).setController(this);
273 }
274 else if(view instanceof ToolView){
275 ((ToolView) view).setController(this);
276 }
277 }
278
279 public <V extends Enum<?>> void setDefaultView(V viewType){
280 this.defaultView = viewType;
281 }
282
283 public Enum<?> getDefaultView(){
284 return this.defaultView;
285 }
286
287 public abstract void updateModel();
288
289 public void updateModelFromView(Enum<?> viewType){
290 View v = viewMap.get(viewType);
291 if(v != null){
292 v.updateModel();
293 }
294 }
295
296 public void updateModelFromCurrentView(){
297 if(this.getCurrentView() != null){
298 this.getCurrentView().updateModel();
299 }
300 }
301
302
303 @Override
304 public <V extends Enum<?>> void getView(V viewType, Callback<View> callback) {
305 callback.exec(viewMap.get(viewType));
306 }
307
308 @Override
309 public Enum<?> getViewEnumValue(String enumValue) {
310 return viewEnumMap.get(enumValue);
311 }
312
313
314 @Override
315 public Class<? extends Enum<?>> getViewsEnum() {
316 return null;
317 }
318
319 @Override
320 public void showDefaultView(final Callback<Boolean> onReadyCallback) {
321 HistoryManager.setLogNavigationHistory(false);
322
323 if(defaultView != null){
324 showView(defaultView, onReadyCallback);
325 }
326 else if(!viewMap.isEmpty()){
327 if(defaultView == null){
328 showView(viewMap.entrySet().iterator().next().getKey(), onReadyCallback);
329 }
330 }
331
332 }
333
334 public void showFirstView(Callback<Boolean> onReadyCallback){
335 HistoryManager.setLogNavigationHistory(false);
336 if(!viewMap.isEmpty()){
337 showView(viewMap.entrySet().iterator().next().getKey(), onReadyCallback);
338 }
339 else{
340 showDefaultView(onReadyCallback);
341 }
342 }
343
344
345
346
347
348
349
350
351 public boolean isValid(List<ValidationResultInfo> validationResults, boolean checkCurrentSectionOnly){
352 return isValid(validationResults, checkCurrentSectionOnly, true);
353 }
354
355 public boolean isValid(List<ValidationResultInfo> validationResults, boolean checkCurrentSectionOnly, boolean allFields){
356 boolean isValid = true;
357
358 if (checkCurrentSectionOnly){
359
360 View v = getCurrentView();
361 if(v instanceof Section){
362 isValid = isValid(validationResults, (Section)v, allFields);
363 }
364 if(this.isStartViewShowing()){
365 if(startPopupView instanceof Section){
366 isValid = isValid(validationResults, ((Section) startPopupView), allFields) && isValid;
367 }
368 }
369 } else {
370
371 String errorSections = "";
372 StringBuilder errorSectionsbuffer = new StringBuilder();
373 errorSectionsbuffer.append(errorSections);
374 for (Entry<Enum<?>, View> entry:viewMap.entrySet()) {
375 View v = entry.getValue();
376 if (v instanceof Section){
377 if (!isValid(validationResults, (Section)v, allFields)){
378 isValid = false;
379 errorSectionsbuffer.append(((SectionView)v).getName() + ", ");
380 }
381 }
382 }
383 if(this.isStartViewShowing()){
384 if(startPopupView instanceof Section){
385 isValid = isValid(validationResults, ((Section) startPopupView), allFields) && isValid;
386 }
387 }
388 errorSections = errorSectionsbuffer.toString();
389 if (!errorSections.isEmpty()){
390 errorSections = errorSections.substring(0, errorSections.length()-2);
391
392 }
393 }
394
395 return isValid;
396 }
397
398 private boolean isValid(List<ValidationResultInfo> validationResults, Section section, boolean allFields){
399 ErrorLevel status;
400 if(allFields){
401 section.setFieldHasHadFocusFlags(true);
402 status = section.processValidationResults(validationResults);
403 }
404 else{
405 status = section.processValidationResults(validationResults, false);
406 }
407
408 return (status != ErrorLevel.ERROR);
409 }
410
411 @Override
412 public void beforeViewChange(Enum<?> viewChangingTo, Callback<Boolean> okToChange) {
413 if(this.getCurrentView() instanceof Controller){
414 ((Controller)this.getCurrentView()).beforeViewChange(viewChangingTo, okToChange);
415 }
416 else{
417 okToChange.exec(true);
418 }
419 }
420
421 @Override
422 public Widget asWidget() {
423 return this;
424 }
425
426 @Override
427 public boolean beforeHide() {
428 return true;
429 }
430
431 @Override
432 public void beforeShow(Callback<Boolean> onReadyCallback) {
433 onReadyCallback.exec(true);
434 }
435
436 @Override
437 public Controller getController() {
438 return parentController;
439 }
440
441 @Override
442 public String getName() {
443 if(name == null && viewType != null){
444 return viewType.toString();
445 }
446 else{
447 return name;
448 }
449 }
450
451 @Override
452 public Enum<?> getViewEnum() {
453 return viewType;
454 }
455
456 public void setViewEnum(Enum<?> viewType){
457 this.viewType= viewType;
458 }
459
460 public void setName(String name){
461 this.name = name;
462 }
463
464 public void setController(Controller controller){
465 parentController = controller;
466 }
467
468 @Override
469 public void collectBreadcrumbNames(List<String> names) {
470 names.add(this.getName());
471 if(this.getCurrentView() != null){
472 this.getCurrentView().collectBreadcrumbNames(names);
473 }
474 }
475
476 @Override
477 public void clear() {
478
479 }
480
481 }