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