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