Coverage Report - org.kuali.student.common.ui.client.mvc.Controller
 
Classes in this File Line Coverage Branch Coverage Complexity
Controller
0%
0/129
0%
0/66
2.208
Controller$1
0%
0/2
N/A
2.208
Controller$2
0%
0/6
0%
0/2
2.208
Controller$3
0%
0/19
0%
0/14
2.208
Controller$3$1
0%
0/6
N/A
2.208
Controller$4
0%
0/14
0%
0/6
2.208
Controller$5
0%
0/24
0%
0/20
2.208
Controller$5$1
0%
0/4
0%
0/2
2.208
Controller$6
0%
0/4
0%
0/2
2.208
Controller$7
0%
0/9
N/A
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  
 }