Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
Controller |
|
| 2.2083333333333335;2.208 | ||||
Controller$1 |
|
| 2.2083333333333335;2.208 | ||||
Controller$2 |
|
| 2.2083333333333335;2.208 | ||||
Controller$3 |
|
| 2.2083333333333335;2.208 | ||||
Controller$3$1 |
|
| 2.2083333333333335;2.208 | ||||
Controller$4 |
|
| 2.2083333333333335;2.208 | ||||
Controller$5 |
|
| 2.2083333333333335;2.208 | ||||
Controller$5$1 |
|
| 2.2083333333333335;2.208 | ||||
Controller$6 |
|
| 2.2083333333333335;2.208 | ||||
Controller$7 |
|
| 2.2083333333333335;2.208 |
1 | /** | |
2 | * Copyright 2010 The Kuali Foundation Licensed under the | |
3 | * Educational Community License, Version 2.0 (the "License"); you may | |
4 | * not use this file except in compliance with the License. You may | |
5 | * obtain a copy of the License at | |
6 | * | |
7 | * http://www.osedu.org/licenses/ECL-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, | |
10 | * software distributed under the License is distributed on an "AS IS" | |
11 | * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | |
12 | * or implied. See the License for the specific language governing | |
13 | * permissions and limitations under the License. | |
14 | */ | |
15 | ||
16 | package org.kuali.student.common.ui.client.mvc; | |
17 | ||
18 | import java.util.ArrayList; | |
19 | import java.util.HashMap; | |
20 | import java.util.Iterator; | |
21 | import java.util.List; | |
22 | import java.util.Map; | |
23 | ||
24 | import org.kuali.student.common.assembly.data.Data; | |
25 | import org.kuali.student.common.rice.authorization.PermissionType; | |
26 | import org.kuali.student.common.ui.client.application.KSAsyncCallback; | |
27 | import org.kuali.student.common.ui.client.application.ViewContext; | |
28 | import org.kuali.student.common.ui.client.configurable.mvc.LayoutController; | |
29 | import org.kuali.student.common.ui.client.configurable.mvc.views.SectionView; | |
30 | import org.kuali.student.common.ui.client.mvc.breadcrumb.BreadcrumbSupport; | |
31 | import org.kuali.student.common.ui.client.mvc.history.HistoryManager; | |
32 | import org.kuali.student.common.ui.client.mvc.history.HistorySupport; | |
33 | import org.kuali.student.common.ui.client.mvc.history.NavigationEvent; | |
34 | import org.kuali.student.common.ui.client.reporting.ReportExport; | |
35 | import org.kuali.student.common.ui.client.security.AuthorizationCallback; | |
36 | import org.kuali.student.common.ui.client.security.RequiresAuthorization; | |
37 | import org.kuali.student.common.ui.client.service.GwtExportRpcService; | |
38 | import org.kuali.student.common.ui.client.service.GwtExportRpcServiceAsync; | |
39 | import org.kuali.student.common.ui.client.util.ExportElement; | |
40 | import org.kuali.student.common.ui.client.util.ExportUtils; | |
41 | import org.kuali.student.common.ui.client.widgets.progress.BlockingTask; | |
42 | import org.kuali.student.common.ui.client.widgets.progress.KSBlockingProgressIndicator; | |
43 | ||
44 | import com.google.gwt.core.client.GWT; | |
45 | import com.google.gwt.event.shared.HandlerManager; | |
46 | import com.google.gwt.event.shared.HandlerRegistration; | |
47 | import com.google.gwt.event.shared.GwtEvent.Type; | |
48 | import com.google.gwt.user.client.Window; | |
49 | import com.google.gwt.user.client.ui.Composite; | |
50 | import com.google.gwt.user.client.ui.Widget; | |
51 | ||
52 | /** | |
53 | * Abstract Controller composite. Provides basic controller operations, and defines abstract methods that a composite must | |
54 | * implement in order to be a controller. | |
55 | * | |
56 | * @author Kuali Student Team | |
57 | */ | |
58 | 0 | public abstract class Controller extends Composite implements HistorySupport, BreadcrumbSupport, ReportExport{ |
59 | 0 | public static final Callback<Boolean> NO_OP_CALLBACK = new Callback<Boolean>() { |
60 | @Override | |
61 | public void exec(Boolean result) { | |
62 | // do nothing | |
63 | 0 | } |
64 | }; | |
65 | ||
66 | 0 | protected Controller parentController = null; |
67 | 0 | private View currentView = null; |
68 | 0 | private Enum<?> currentViewEnum = null; |
69 | 0 | private String defaultModelId = null; |
70 | 0 | protected ViewContext context = new ViewContext(); |
71 | 0 | private final Map<String, ModelProvider<? extends Model>> models = new HashMap<String, ModelProvider<? extends Model>>(); |
72 | 0 | private boolean fireNavEvents = true; |
73 | 0 | private HandlerManager applicationEventHandlers = new HandlerManager(this); |
74 | 0 | private GwtExportRpcServiceAsync reportExportRpcService = GWT.create(GwtExportRpcService.class); |
75 | ||
76 | 0 | protected Controller() { |
77 | 0 | } |
78 | ||
79 | /** | |
80 | * Simple Version of showView, no callback | |
81 | * @param <V> | |
82 | * view enum type | |
83 | * @param viewType | |
84 | * enum value representing the view to show | |
85 | */ | |
86 | public <V extends Enum<?>> void showView(final V viewType){ | |
87 | 0 | this.showView(viewType, NO_OP_CALLBACK); |
88 | 0 | } |
89 | ||
90 | ||
91 | ||
92 | /** | |
93 | * Directs the controller to display the specified view. The parameter must be an enum value, based on an enum defined in | |
94 | * the controller implementation. For example, a "Search" controller might have an enumeration of: <code> | |
95 | * public enum SearchViews { | |
96 | * SIMPLE_SEARCH, | |
97 | * ADVANCED_SEARCH, | |
98 | * SEARCH_RESULTS | |
99 | * } | |
100 | * </code> The implementing class must define a getView(V viewType) method that will cast the generic enum to the view | |
101 | * specific enum. | |
102 | * | |
103 | * @param <V> | |
104 | * view enum type | |
105 | * @param viewType | |
106 | * enum value representing the view to show | |
107 | * @param onReadyCallback the callback to invoke when the method has completed execution | |
108 | * @return false if the current view cancels the operation | |
109 | */ | |
110 | public <V extends Enum<?>> void showView(final V viewType, final Callback<Boolean> onReadyCallback) { | |
111 | 0 | GWT.log("showView " + viewType.toString(), null); |
112 | 0 | getView(viewType, new Callback<View>(){ |
113 | ||
114 | @Override | |
115 | public void exec(View result) { | |
116 | 0 | View view = result; |
117 | 0 | if (view == null) { |
118 | 0 | onReadyCallback.exec(false); |
119 | //throw new ControllerException("View not registered: " + viewType.toString()); | |
120 | } | |
121 | 0 | beginShowView(view, viewType, onReadyCallback); |
122 | ||
123 | 0 | }},null); |
124 | 0 | } |
125 | ||
126 | private <V extends Enum<?>> void beginShowView(final View view, final V viewType, final Callback<Boolean> onReadyCallback){ | |
127 | 0 | beforeViewChange(viewType, new Callback<Boolean>(){ |
128 | ||
129 | @Override | |
130 | public void exec(Boolean result) { | |
131 | 0 | if(result){ |
132 | 0 | boolean requiresAuthz = (view instanceof RequiresAuthorization) && ((RequiresAuthorization)view).isAuthorizationRequired(); |
133 | ||
134 | 0 | if (requiresAuthz){ |
135 | ViewContext tempContext; | |
136 | 0 | if(view instanceof LayoutController){ |
137 | 0 | tempContext = ((LayoutController) view).getViewContext(); |
138 | } | |
139 | else{ | |
140 | 0 | tempContext = view.getController().getViewContext(); |
141 | } | |
142 | ||
143 | 0 | PermissionType permType = (tempContext != null) ? tempContext.getPermissionType() : null; |
144 | 0 | if (permType != null) { |
145 | 0 | GWT.log("Checking permission type '" + permType.getPermissionTemplateName() + "' for view '" + view.toString() + "'", null); |
146 | //A callback is required if async rpc call is required for authz check | |
147 | 0 | ((RequiresAuthorization)view).checkAuthorization(permType, new AuthorizationCallback(){ |
148 | public void isAuthorized() { | |
149 | 0 | finalizeShowView(view, viewType, onReadyCallback); |
150 | 0 | } |
151 | ||
152 | public void isNotAuthorized(String msg) { | |
153 | 0 | Window.alert(msg); |
154 | 0 | onReadyCallback.exec(false); |
155 | 0 | } |
156 | }); | |
157 | } | |
158 | else { | |
159 | 0 | GWT.log("Cannot find PermissionType for view '" + view.toString() + "' which requires authorization", null); |
160 | 0 | finalizeShowView(view, viewType, onReadyCallback); |
161 | } | |
162 | 0 | } else { |
163 | 0 | GWT.log("Not Requiring Auth.", null); |
164 | 0 | finalizeShowView(view, viewType, onReadyCallback); |
165 | } | |
166 | 0 | } |
167 | else{ | |
168 | 0 | onReadyCallback.exec(false); |
169 | } | |
170 | ||
171 | 0 | } |
172 | }); | |
173 | 0 | } |
174 | ||
175 | private <V extends Enum<?>> void finalizeShowView(final View view, final V viewType, final Callback<Boolean> onReadyCallback){ | |
176 | 0 | if (((currentView == null) || currentView.beforeHide()) && view != null) { |
177 | 0 | view.beforeShow(new Callback<Boolean>() { |
178 | @Override | |
179 | public void exec(Boolean result) { | |
180 | 0 | if (!result) { |
181 | 0 | GWT.log("showView: beforeShow yielded false " + viewType, null); |
182 | 0 | onReadyCallback.exec(false); |
183 | } else { | |
184 | 0 | if (currentView != null) { |
185 | 0 | hideView(currentView); |
186 | } | |
187 | ||
188 | 0 | currentViewEnum = viewType; |
189 | 0 | currentView = view; |
190 | 0 | GWT.log("renderView " + viewType.toString(), null); |
191 | 0 | if(fireNavEvents){ |
192 | 0 | fireNavigationEvent(); |
193 | } | |
194 | 0 | renderView(view); |
195 | 0 | onReadyCallback.exec(true); |
196 | ||
197 | } | |
198 | 0 | } |
199 | }); | |
200 | } else { | |
201 | 0 | onReadyCallback.exec(false); |
202 | 0 | GWT.log("Current view canceled hide action", null); |
203 | } | |
204 | 0 | } |
205 | ||
206 | protected void fireNavigationEvent() { | |
207 | //DeferredCommand.addCommand(new Command() { | |
208 | // @Override | |
209 | //public void execute() { | |
210 | 0 | fireApplicationEvent(new NavigationEvent(Controller.this)); |
211 | //} | |
212 | //}); | |
213 | 0 | } |
214 | ||
215 | /** | |
216 | * Returns the currently displayed view | |
217 | * | |
218 | * @return the currently displayed view | |
219 | */ | |
220 | public View getCurrentView() { | |
221 | 0 | return currentView; |
222 | } | |
223 | ||
224 | public Enum<?> getCurrentViewEnum() { | |
225 | 0 | return currentViewEnum; |
226 | } | |
227 | ||
228 | public void setCurrentViewEnum(Enum<?> currentViewEnum) { | |
229 | 0 | this.currentViewEnum = currentViewEnum; |
230 | 0 | } |
231 | ||
232 | /** | |
233 | * Sets the controller's parent controller. In most cases, this can be omitted as the controller will be automatically | |
234 | * detected via the DOM in cases where it is not specified. The only time that the controller needs to be manually set is | |
235 | * in cases where the logical controller hierarchy differs from the physical DOM hierarchy. For example, if a nested | |
236 | * controller is rendered in a PopupPanel, then the parent controller must be set manually using this method | |
237 | * | |
238 | * @param controller | |
239 | * the parent controller | |
240 | */ | |
241 | public void setParentController(Controller controller) { | |
242 | 0 | parentController = controller; |
243 | 0 | } |
244 | ||
245 | /** | |
246 | * Returns the parent controller. If the current parent controller is not set, then the controller will attempt to | |
247 | * automatically locate the parent controller via the DOM. | |
248 | * | |
249 | * @return | |
250 | */ | |
251 | public Controller getParentController() { | |
252 | 0 | if (parentController == null) { |
253 | 0 | parentController = Controller.findController(this); |
254 | } | |
255 | 0 | return parentController; |
256 | } | |
257 | ||
258 | /** | |
259 | * Attempts to find the parent controller of a given widget via the DOM | |
260 | * | |
261 | * @param w | |
262 | * the widget for which to find the parent controller | |
263 | * @return the controller, or null if not found | |
264 | */ | |
265 | public static Controller findController(Widget w) { | |
266 | 0 | Controller result = null; |
267 | while (true) { | |
268 | 0 | w = w.getParent(); |
269 | 0 | if (w == null) { |
270 | 0 | break; |
271 | 0 | } else if (w instanceof Controller) { |
272 | 0 | result = (Controller) w; |
273 | 0 | break; |
274 | 0 | } else if (w instanceof View) { |
275 | // this is in the event that a parent/child relationship is broken by a view being rendered in a lightbox, | |
276 | // etc | |
277 | 0 | result = ((View) w).getController(); |
278 | 0 | break; |
279 | } | |
280 | } | |
281 | 0 | return result; |
282 | } | |
283 | ||
284 | /** | |
285 | * Called by child views and controllers to request a model reference. By default it delegates calls to the parent | |
286 | * controller if one is found. Override this method to declare a model local to the controller. Always make sure to | |
287 | * delegate the call to the superclass if the requested type is not one which is defined locally. For example: <code> | |
288 | * | |
289 | * @Override | |
290 | * @SuppressWarnings("unchecked") public void requestModel(Class<? extends Idable> modelType, ModelRequestCallback | |
291 | * callback) { if (modelType.equals(Address.class)) { callback.onModelReady(addresses); } | |
292 | * else { super.requestModel(modelType, callback); } } </code> | |
293 | * @param modelType | |
294 | * @param callback | |
295 | */ | |
296 | @SuppressWarnings("unchecked") | |
297 | public void requestModel(final Class modelType, final ModelRequestCallback callback) { | |
298 | 0 | requestModel((modelType == null) ? null : modelType.getName(), callback); |
299 | 0 | } |
300 | ||
301 | @SuppressWarnings("unchecked") | |
302 | public void requestModel(final String modelId, final ModelRequestCallback callback) { | |
303 | 0 | String id = (modelId == null) ? defaultModelId : modelId; |
304 | ||
305 | 0 | ModelProvider<? extends Model> p = models.get(id); |
306 | 0 | if (p != null) { |
307 | 0 | p.requestModel(callback); |
308 | 0 | } else if (getParentController() != null) { |
309 | 0 | parentController.requestModel(modelId, callback); |
310 | } else { | |
311 | 0 | if (callback != null) { |
312 | 0 | callback.onRequestFail(new RuntimeException("The requested model was not found: " + modelId)); |
313 | } | |
314 | } | |
315 | 0 | } |
316 | ||
317 | @SuppressWarnings("unchecked") | |
318 | public void requestModel(final ModelRequestCallback callback) { | |
319 | 0 | requestModel((String)null, callback); |
320 | 0 | } |
321 | ||
322 | public <T extends Model> void registerModel(String modelId, ModelProvider<T> provider) { | |
323 | 0 | models.put(modelId, provider); |
324 | 0 | } |
325 | ||
326 | public String getDefaultModelId() { | |
327 | 0 | return defaultModelId; |
328 | } | |
329 | public void setDefaultModelId(String defaultModelId) { | |
330 | 0 | this.defaultModelId = defaultModelId; |
331 | 0 | } |
332 | ||
333 | /** | |
334 | * Registers an application eventhandler. The controller will try to propagate "unchecked" handlers to the parent | |
335 | * controller if a parent controller exists. This method can be overridden to handle unchecked locally if they are fired | |
336 | * locally. | |
337 | * | |
338 | * @param type | |
339 | * @param handler | |
340 | * @return | |
341 | */ | |
342 | @SuppressWarnings("unchecked") | |
343 | public HandlerRegistration addApplicationEventHandler(Type type, ApplicationEventHandler handler) { | |
344 | 0 | if ((handler instanceof UncheckedApplicationEventHandler) && (getParentController() != null)) { |
345 | 0 | return parentController.addApplicationEventHandler(type, handler); |
346 | } | |
347 | 0 | return applicationEventHandlers.addHandler(type, handler); |
348 | } | |
349 | ||
350 | /** | |
351 | * Fires an application event. | |
352 | * | |
353 | * @param event | |
354 | */ | |
355 | @SuppressWarnings("unchecked") | |
356 | public void fireApplicationEvent(ApplicationEvent event) { | |
357 | // TODO this logic needs to be reworked a bit... if an unchecked event has been bound locally, do we want to still | |
358 | // fire it externally as well? | |
359 | 0 | if ((event instanceof UncheckedApplicationEvent) && (getParentController() != null)) { |
360 | 0 | parentController.fireApplicationEvent(event); |
361 | } | |
362 | // dispatch to local "checked" handlers, and to any unchecked handlers that have been bound to local | |
363 | 0 | applicationEventHandlers.fireEvent(event); |
364 | ||
365 | 0 | } |
366 | ||
367 | /** | |
368 | * Must be implemented by the subclass to render the view. | |
369 | * | |
370 | * @param view | |
371 | */ | |
372 | protected abstract void renderView(View view); | |
373 | ||
374 | /** | |
375 | * Must be implemented by the subclass to hide the view. | |
376 | * | |
377 | * @param view | |
378 | */ | |
379 | protected abstract void hideView(View view); | |
380 | ||
381 | /** | |
382 | * Returns the view associated with the specified enum value. See showView(V viewType) above for a full description | |
383 | * defaults to the abstract get view method unless overridden | |
384 | * @param <V> | |
385 | * @param viewType | |
386 | * @param callback | |
387 | * @param tokenMap optionally passed in token map if you need tokens from the history manager | |
388 | */ | |
389 | protected <V extends Enum<?>> void getView(V viewType, Callback<View> callback, Map<String, String> tokenMap){ | |
390 | 0 | getView(viewType, callback); |
391 | 0 | } |
392 | ||
393 | /** | |
394 | * Returns the view associated with the specified enum value. See showView(V viewType) above for a full description | |
395 | * | |
396 | * @param <V> | |
397 | * @param viewType | |
398 | * @return | |
399 | */ | |
400 | protected abstract <V extends Enum<?>> void getView(V viewType, Callback<View> callback); | |
401 | ||
402 | /** | |
403 | * If a controller which extends this class must perform some action or check before a view | |
404 | * is changed, then override this method. Do not call super() in the override, as it will | |
405 | * allow the view to continue to change. | |
406 | * @param okToChangeCallback | |
407 | */ | |
408 | public void beforeViewChange(Enum<?> viewChangingTo, Callback<Boolean> okToChangeCallback) { | |
409 | 0 | okToChangeCallback.exec(true); |
410 | 0 | } |
411 | ||
412 | /** | |
413 | * Shows the default view. Must be implemented by subclass, in order to define the default view. | |
414 | */ | |
415 | public abstract void showDefaultView(Callback<Boolean> onReadyCallback); | |
416 | ||
417 | public abstract Enum<?> getViewEnumValue(String enumValue); | |
418 | ||
419 | /** | |
420 | * This particular implementation appends to the history stack the name of the current view shown by | |
421 | * this controller and view context (in string format) to that historyStack and passes the stack to | |
422 | * be processed to the currentView. | |
423 | * @see org.kuali.student.common.ui.client.mvc.history.HistorySupport#collectHistory(java.lang.String) | |
424 | */ | |
425 | @Override | |
426 | public String collectHistory(String historyStack) { | |
427 | 0 | String token = getHistoryToken(); |
428 | 0 | historyStack = historyStack + "/" + token; |
429 | ||
430 | 0 | if(currentView != null){ |
431 | 0 | String tempHistoryStack = historyStack; |
432 | 0 | historyStack = currentView.collectHistory(historyStack); |
433 | ||
434 | //Sanity check, if collectHistory returns null or empty string, restore | |
435 | 0 | if(historyStack == null){ |
436 | 0 | historyStack = tempHistoryStack; |
437 | } | |
438 | 0 | else if(historyStack != null && historyStack.isEmpty()){ |
439 | 0 | historyStack = tempHistoryStack; |
440 | } | |
441 | } | |
442 | 0 | return historyStack; |
443 | } | |
444 | ||
445 | protected String getHistoryToken() { | |
446 | 0 | String historyToken = ""; |
447 | 0 | if (currentViewEnum != null) { |
448 | 0 | historyToken = currentViewEnum.toString(); |
449 | 0 | if(currentView != null && currentView instanceof Controller |
450 | && ((Controller)currentView).getViewContext() != null){ | |
451 | 0 | ViewContext context = ((Controller) currentView).getViewContext(); |
452 | 0 | historyToken = HistoryManager.appendContext(historyToken, context); |
453 | } | |
454 | ||
455 | } | |
456 | 0 | return historyToken; |
457 | } | |
458 | ||
459 | /** | |
460 | * The onHistoryEvent implementation in controller reads the history stack it receives and determines | |
461 | * if the next token/view to be processed is a controller, if it is, it hands off the rest of the history stack | |
462 | * to that controller after showing it. Otherwise, it shows the view | |
463 | * and allows that view to perform any onHistoryEvent actions it may need to take. | |
464 | * <br><br>For example the historyStack /HOME/CURRICULUM_HOME/COURSE_PROPOSAL would start at the root controller, | |
465 | * and hand it off to the home controller, then the curriculum home controller, then the course proposal controller | |
466 | * and stop there. Along the way each of those controller would show themselves visually in the UI, | |
467 | * if they contain any layout (some do not). | |
468 | * | |
469 | * @see org.kuali.student.common.ui.client.mvc.history.HistorySupport#onHistoryEvent(java.lang.String) | |
470 | */ | |
471 | @Override | |
472 | public void onHistoryEvent(String historyStack) { | |
473 | 0 | final String nextHistoryStack = HistoryManager.nextHistoryStack(historyStack); |
474 | 0 | String[] tokens = HistoryManager.splitHistoryStack(nextHistoryStack); |
475 | 0 | if (tokens.length >= 1 && tokens[0] != null && !tokens[0].isEmpty()) { |
476 | 0 | final Map<String, String> tokenMap = HistoryManager.getTokenMap(tokens[0]); |
477 | //TODO add some automatic view context setting here, get and set | |
478 | 0 | String viewEnumString = tokenMap.get("view"); |
479 | 0 | if (viewEnumString != null) { |
480 | 0 | final Enum<?> viewEnum = getViewEnumValue(viewEnumString); |
481 | ||
482 | 0 | if (viewEnum != null) { |
483 | 0 | getView(viewEnum, new Callback<View>(){ |
484 | ||
485 | @Override | |
486 | public void exec(View result) { | |
487 | 0 | View theView = result; |
488 | 0 | boolean sameContext = true; |
489 | 0 | if(theView instanceof Controller){ |
490 | ||
491 | 0 | ViewContext newContext = new ViewContext(); |
492 | 0 | Iterator<String> tokenIt = tokenMap.keySet().iterator(); |
493 | 0 | while(tokenIt.hasNext()){ |
494 | 0 | String key = tokenIt.next(); |
495 | 0 | if(key.equals(ViewContext.ID_ATR)){ |
496 | 0 | newContext.setId(tokenMap.get(ViewContext.ID_ATR)); |
497 | } | |
498 | 0 | else if(key.equals(ViewContext.ID_TYPE_ATR)){ |
499 | 0 | newContext.setIdType(tokenMap.get(ViewContext.ID_TYPE_ATR)); |
500 | } | |
501 | //do not add view attribute from the token map to the context | |
502 | 0 | else if(!key.equals("view")){ |
503 | 0 | newContext.setAttribute(key, tokenMap.get(key)); |
504 | } | |
505 | 0 | } |
506 | ||
507 | 0 | ViewContext viewContext = ((Controller) theView).getViewContext(); |
508 | 0 | if(viewContext.compareTo(newContext) != 0){ |
509 | 0 | ((Controller) theView).setViewContext(newContext); |
510 | 0 | sameContext = false; |
511 | } | |
512 | } | |
513 | 0 | if (currentViewEnum == null || !viewEnum.equals(currentViewEnum) |
514 | || !sameContext) { | |
515 | 0 | beginShowView(theView, viewEnum, new Callback<Boolean>() { |
516 | @Override | |
517 | public void exec(Boolean result) { | |
518 | 0 | if (result) { |
519 | 0 | currentView.onHistoryEvent(nextHistoryStack); |
520 | } | |
521 | 0 | } |
522 | }); | |
523 | 0 | } else if (currentView != null) { |
524 | 0 | currentView.onHistoryEvent(nextHistoryStack); |
525 | } | |
526 | 0 | } |
527 | },tokenMap); | |
528 | ||
529 | } | |
530 | } | |
531 | 0 | } |
532 | else{ | |
533 | 0 | this.showDefaultView(new Callback<Boolean>(){ |
534 | ||
535 | @Override | |
536 | public void exec(Boolean result) { | |
537 | 0 | if(result){ |
538 | 0 | currentView.onHistoryEvent(nextHistoryStack); |
539 | } | |
540 | ||
541 | 0 | } |
542 | }); | |
543 | } | |
544 | ||
545 | 0 | } |
546 | ||
547 | /** | |
548 | * Sets the view context. This is important for determining the permission for seeing views under | |
549 | * this controllers scope, what the id and id type of the model the controller handles are defined here. | |
550 | * Additional attributes that the controller and it's views need to know about are also defined in the | |
551 | * viewContext. | |
552 | * @param viewContext | |
553 | */ | |
554 | public void setViewContext(ViewContext viewContext){ | |
555 | 0 | this.context = viewContext; |
556 | 0 | } |
557 | ||
558 | public ViewContext getViewContext() { | |
559 | 0 | return this.context; |
560 | } | |
561 | ||
562 | public void resetCurrentView(){ | |
563 | 0 | currentView = null; |
564 | 0 | } |
565 | ||
566 | /** | |
567 | * | |
568 | * This method implement the "Generic Export" of a windows content to Jasper based on the format the user selected. | |
569 | * This method can be overwritten on a subclass to do specific export to the specific view | |
570 | * | |
571 | * @see org.kuali.student.common.ui.client.reporting.ReportExport#doReportExport(java.util.ArrayList) | |
572 | */ | |
573 | @Override | |
574 | public void doReportExport(List<ExportElement> exportElements, final String format, final String reportTitle) { | |
575 | // Service call... | |
576 | 0 | final BlockingTask loadDataTask = new BlockingTask("Generating Export File"); |
577 | ||
578 | 0 | DataModel dataModel = getExportDataModel(); |
579 | 0 | Data modelDataObject = null; |
580 | 0 | if (dataModel != null) { |
581 | 0 | modelDataObject = dataModel.getRoot(); |
582 | } | |
583 | ||
584 | ||
585 | // we want to show that something is happening while the files are generated. | |
586 | 0 | KSBlockingProgressIndicator.addTask(loadDataTask); |
587 | ||
588 | 0 | reportExportRpcService.reportExport(exportElements, modelDataObject, getExportTemplateName(), format, reportTitle, new KSAsyncCallback<String>() { |
589 | @Override | |
590 | public void onSuccess(String result) { | |
591 | // On success get documentID back from GWT Servlet// | |
592 | ||
593 | // We need to get the base url and strip the gwt module name . | |
594 | 0 | String baseUrl = GWT.getHostPageBaseURL(); |
595 | 0 | baseUrl = baseUrl.replaceFirst(GWT.getModuleName() + "/", ""); |
596 | ||
597 | 0 | KSBlockingProgressIndicator.removeTask(loadDataTask); |
598 | ||
599 | 0 | Window.open(baseUrl + "exportDownloadHTTPServlet?exportId="+result + "&format=" + format, "", ""); |
600 | 0 | } |
601 | ||
602 | @Override | |
603 | public void handleFailure(Throwable caught) { | |
604 | 0 | KSBlockingProgressIndicator.removeTask(loadDataTask); |
605 | 0 | super.handleFailure(caught); |
606 | 0 | } |
607 | ||
608 | }); | |
609 | ||
610 | ||
611 | ||
612 | 0 | } |
613 | ||
614 | // TODO Nina ??? Do we want to keep this seen in the light of the exportElements parameter | |
615 | @Override | |
616 | public DataModel getExportDataModel() { | |
617 | 0 | return null; |
618 | } | |
619 | ||
620 | /** | |
621 | * | |
622 | * @see org.kuali.student.common.ui.client.reporting.ReportExport#getExportTemplateName() | |
623 | */ | |
624 | @Override | |
625 | public String getExportTemplateName() { | |
626 | 0 | return exportTemplateName; |
627 | } | |
628 | ||
629 | @Override | |
630 | public List<ExportElement> getExportElementsFromView() { | |
631 | 0 | String viewName = null; |
632 | 0 | View currentView = this.getCurrentView(); |
633 | 0 | if (currentView != null) { |
634 | ||
635 | 0 | ArrayList<ExportElement> exportElements = null; |
636 | ||
637 | 0 | if (currentView != null && currentView instanceof SectionView) { |
638 | 0 | viewName = currentView.getName(); |
639 | 0 | exportElements = ExportUtils.getExportElementsFromView((SectionView)currentView, exportElements, viewName, "Sectionname"); |
640 | 0 | return exportElements; |
641 | } else { | |
642 | // logger.warn("ExportUtils.getExportElementsFromView not implemented for :" + this.getCurrentView()); | |
643 | } | |
644 | } else { | |
645 | // logger.warn("ExportUtils.getExportElementsFromView controller currentView is null :" + this.getClass().getName()); | |
646 | } | |
647 | 0 | return null; |
648 | } | |
649 | } |