Coverage Report - org.kuali.rice.krad.web.controller.UifControllerBase
 
Classes in this File Line Coverage Branch Coverage Complexity
UifControllerBase
0%
0/185
0%
0/72
2.962
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.krad.web.controller;
 17  
 
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.kuali.rice.core.api.config.property.ConfigContext;
 20  
 import org.kuali.rice.core.api.exception.RiceRuntimeException;
 21  
 import org.kuali.rice.core.web.format.BooleanFormatter;
 22  
 import org.kuali.rice.kim.api.KimConstants;
 23  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 24  
 import org.kuali.rice.krad.UserSession;
 25  
 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
 26  
 import org.kuali.rice.krad.exception.AuthorizationException;
 27  
 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
 28  
 import org.kuali.rice.krad.service.ModuleService;
 29  
 import org.kuali.rice.krad.service.SessionDocumentService;
 30  
 import org.kuali.rice.krad.uif.UifConstants;
 31  
 import org.kuali.rice.krad.uif.UifParameters;
 32  
 import org.kuali.rice.krad.uif.UifPropertyPaths;
 33  
 import org.kuali.rice.krad.uif.component.Component;
 34  
 import org.kuali.rice.krad.uif.container.CollectionGroup;
 35  
 import org.kuali.rice.krad.uif.field.AttributeQueryResult;
 36  
 import org.kuali.rice.krad.uif.service.ViewService;
 37  
 import org.kuali.rice.krad.uif.util.ComponentFactory;
 38  
 import org.kuali.rice.krad.uif.util.LookupInquiryUtils;
 39  
 import org.kuali.rice.krad.uif.util.UifWebUtils;
 40  
 import org.kuali.rice.krad.uif.view.History;
 41  
 import org.kuali.rice.krad.uif.view.HistoryEntry;
 42  
 import org.kuali.rice.krad.uif.view.View;
 43  
 import org.kuali.rice.krad.util.GlobalVariables;
 44  
 import org.kuali.rice.krad.util.KRADConstants;
 45  
 import org.kuali.rice.krad.util.KRADUtils;
 46  
 import org.kuali.rice.krad.util.UrlFactory;
 47  
 import org.kuali.rice.krad.web.form.UifFormBase;
 48  
 import org.springframework.validation.BindingResult;
 49  
 import org.springframework.web.bind.annotation.ModelAttribute;
 50  
 import org.springframework.web.bind.annotation.RequestMapping;
 51  
 import org.springframework.web.bind.annotation.RequestMethod;
 52  
 import org.springframework.web.bind.annotation.ResponseBody;
 53  
 import org.springframework.web.servlet.ModelAndView;
 54  
 
 55  
 import javax.servlet.http.HttpServletRequest;
 56  
 import javax.servlet.http.HttpServletResponse;
 57  
 import java.util.Collections;
 58  
 import java.util.HashMap;
 59  
 import java.util.HashSet;
 60  
 import java.util.List;
 61  
 import java.util.Map;
 62  
 import java.util.Map.Entry;
 63  
 import java.util.Properties;
 64  
 import java.util.Set;
 65  
 
 66  
 /**
 67  
  * Base controller class for views within the KRAD User Interface Framework
 68  
  *
 69  
  * Provides common methods such as:
 70  
  *
 71  
  * <ul>
 72  
  * <li>Authorization methods such as method to call check</li>
 73  
  * <li>Preparing the View instance and setup in the returned
 74  
  * <code>ModelAndView</code></li>
 75  
  * </ul>
 76  
  *
 77  
  * All subclass controller methods after processing should call one of the
 78  
  * #getUIFModelAndView methods to setup the <code>View</code> and return the
 79  
  * <code>ModelAndView</code> instance.
 80  
  *
 81  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 82  
  */
 83  0
 public abstract class UifControllerBase {
 84  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(UifControllerBase.class);
 85  
 
 86  
     protected static final String REDIRECT_PREFIX = "redirect:";
 87  
 
 88  
     /**
 89  
      * Create/obtain the model(form) object before it is passed
 90  
      * to the Binder/BeanWrapper. This method is not intended to be overridden
 91  
      * by client applications as it handles framework setup and session
 92  
      * maintenance. Clients should override createIntialForm() instead when they
 93  
      * need custom form initialization.
 94  
      */
 95  
     @ModelAttribute(value = "KualiForm")
 96  
     public UifFormBase initForm(HttpServletRequest request) {
 97  0
         UifFormBase form = null;
 98  0
         String formKeyParam = request.getParameter(UifParameters.FORM_KEY);
 99  0
         String documentNumber = request.getParameter(KRADConstants.DOCUMENT_DOCUMENT_NUMBER);
 100  
 
 101  0
         if (StringUtils.isNotBlank(formKeyParam)) {
 102  0
             form = (UifFormBase) request.getSession().getAttribute(formKeyParam);
 103  
 
 104  
             // retrieve from db if form not in session
 105  0
             if (form == null) {
 106  0
                 UserSession userSession = (UserSession) request.getSession().getAttribute(
 107  
                         KRADConstants.USER_SESSION_KEY);
 108  0
                 form = getSessionDocumentService().getDocumentForm(documentNumber, formKeyParam, userSession,
 109  
                         request.getRemoteAddr());
 110  0
             }
 111  
         } else {
 112  0
             form = createInitialForm(request);
 113  
         }
 114  
 
 115  0
         return form;
 116  
     }
 117  
 
 118  
     /**
 119  
      * Called to create a new model(form) object when
 120  
      * necessary. This usually occurs on the initial request in a conversation
 121  
      * (when the model is not present in the session). This method must be
 122  
      * overridden when extending a controller and using a different form type
 123  
      * than the superclass.
 124  
      */
 125  
     protected abstract UifFormBase createInitialForm(HttpServletRequest request);
 126  
 
 127  0
     private Set<String> methodToCallsToNotCheckAuthorization = new HashSet<String>();
 128  
 
 129  
     {
 130  0
         methodToCallsToNotCheckAuthorization.add("performLookup");
 131  0
         methodToCallsToNotCheckAuthorization.add("performQuestion");
 132  0
         methodToCallsToNotCheckAuthorization.add("performQuestionWithInput");
 133  0
         methodToCallsToNotCheckAuthorization.add("performQuestionWithInputAgainBecauseOfErrors");
 134  0
         methodToCallsToNotCheckAuthorization.add("performQuestionWithoutInput");
 135  0
         methodToCallsToNotCheckAuthorization.add("performWorkgroupLookup");
 136  0
     }
 137  
 
 138  
     /**
 139  
      * Use to add a methodToCall to the a list which will not have authorization
 140  
      * checks. This assumes that the call will be redirected (as in the case of
 141  
      * a lookup) that will perform the authorization.
 142  
      */
 143  
     protected final void addMethodToCallToUncheckedList(String methodToCall) {
 144  0
         methodToCallsToNotCheckAuthorization.add(methodToCall);
 145  0
     }
 146  
 
 147  
     /**
 148  
      * Returns an immutable Set of methodToCall parameters that should not be
 149  
      * checked for authorization.
 150  
      */
 151  
     public Set<String> getMethodToCallsToNotCheckAuthorization() {
 152  0
         return Collections.unmodifiableSet(methodToCallsToNotCheckAuthorization);
 153  
     }
 154  
 
 155  
     /**
 156  
      * Override this method to provide controller class-level access controls to
 157  
      * the application.
 158  
      */
 159  
     public void checkAuthorization(UifFormBase form, String methodToCall) throws AuthorizationException {
 160  0
         String principalId = GlobalVariables.getUserSession().getPrincipalId();
 161  0
         Map<String, String> roleQualifier = new HashMap<String, String>(getRoleQualification(form, methodToCall));
 162  0
         Map<String, String> permissionDetails = KRADUtils.getNamespaceAndActionClass(this.getClass());
 163  
 
 164  0
         if (!KimApiServiceLocator.getPermissionService().isAuthorizedByTemplateName(principalId,
 165  
                 KRADConstants.KRAD_NAMESPACE, KimConstants.PermissionTemplateNames.USE_SCREEN, permissionDetails,
 166  
                 roleQualifier)) {
 167  0
             throw new AuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalName(),
 168  
                     methodToCall, this.getClass().getSimpleName());
 169  
         }
 170  0
     }
 171  
 
 172  
     /**
 173  
      * Override this method to add data from the form for role qualification in
 174  
      * the authorization check
 175  
      */
 176  
     protected Map<String, String> getRoleQualification(UifFormBase form, String methodToCall) {
 177  0
         return new HashMap<String, String>();
 178  
     }
 179  
 
 180  
     /**
 181  
      * Initial method called when requesting a new view instance which forwards
 182  
      * the view for rendering
 183  
      */
 184  
     @RequestMapping(method = RequestMethod.GET, params = "methodToCall=start")
 185  
     public ModelAndView start(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
 186  
             HttpServletRequest request, HttpServletResponse response) {
 187  
 
 188  0
         return getUIFModelAndView(form);
 189  
     }
 190  
 
 191  
     /**
 192  
      * Called by the add line action for a new collection line. Method
 193  
      * determines which collection the add action was selected for and invokes
 194  
      * the view helper service to add the line
 195  
      */
 196  
     @RequestMapping(method = RequestMethod.POST, params = "methodToCall=addLine")
 197  
     public ModelAndView addLine(@ModelAttribute("KualiForm") UifFormBase uifForm, BindingResult result,
 198  
             HttpServletRequest request, HttpServletResponse response) {
 199  
 
 200  0
         String selectedCollectionPath = uifForm.getActionParamaterValue(UifParameters.SELLECTED_COLLECTION_PATH);
 201  0
         if (StringUtils.isBlank(selectedCollectionPath)) {
 202  0
             throw new RuntimeException("Selected collection was not set for add line action, cannot add new line");
 203  
         }
 204  
 
 205  0
         View view = uifForm.getPreviousView();
 206  0
         view.getViewHelperService().processCollectionAddLine(view, uifForm, selectedCollectionPath);
 207  
 
 208  0
         return updateComponent(uifForm, result, request, response);
 209  
     }
 210  
 
 211  
     /**
 212  
      * Called by the delete line action for a model collection. Method
 213  
      * determines which collection the action was selected for and the line
 214  
      * index that should be removed, then invokes the view helper service to
 215  
      * process the action
 216  
      */
 217  
     @RequestMapping(method = RequestMethod.POST, params = "methodToCall=deleteLine")
 218  
     public ModelAndView deleteLine(@ModelAttribute("KualiForm") UifFormBase uifForm, BindingResult result,
 219  
             HttpServletRequest request, HttpServletResponse response) {
 220  
 
 221  0
         String selectedCollectionPath = uifForm.getActionParamaterValue(UifParameters.SELLECTED_COLLECTION_PATH);
 222  0
         if (StringUtils.isBlank(selectedCollectionPath)) {
 223  0
             throw new RuntimeException("Selected collection was not set for delete line action, cannot delete line");
 224  
         }
 225  
 
 226  0
         int selectedLineIndex = -1;
 227  0
         String selectedLine = uifForm.getActionParamaterValue(UifParameters.SELECTED_LINE_INDEX);
 228  0
         if (StringUtils.isNotBlank(selectedLine)) {
 229  0
             selectedLineIndex = Integer.parseInt(selectedLine);
 230  
         }
 231  
 
 232  0
         if (selectedLineIndex == -1) {
 233  0
             throw new RuntimeException("Selected line index was not set for delete line action, cannot delete line");
 234  
         }
 235  
 
 236  0
         View view = uifForm.getPreviousView();
 237  0
         view.getViewHelperService().processCollectionDeleteLine(view, uifForm, selectedCollectionPath,
 238  
                 selectedLineIndex);
 239  
 
 240  0
         return updateComponent(uifForm, result, request, response);
 241  
     }
 242  
 
 243  
     /**
 244  
      * Invoked to toggle the show inactive indicator on the selected collection group and then
 245  
      * rerun the component lifecycle and rendering based on the updated indicator and form data
 246  
      *
 247  
      * @param request - request object that should contain the request component id (for the collection group)
 248  
      * and the show inactive indicator value
 249  
      */
 250  
     @RequestMapping(method = RequestMethod.POST, params = "methodToCall=toggleInactiveRecordDisplay")
 251  
     public ModelAndView toggleInactiveRecordDisplay(@ModelAttribute("KualiForm") UifFormBase uifForm,
 252  
             BindingResult result, HttpServletRequest request, HttpServletResponse response) {
 253  0
         String collectionGroupId = request.getParameter(UifParameters.REQUESTED_COMPONENT_ID);
 254  0
         if (StringUtils.isBlank(collectionGroupId)) {
 255  0
             throw new RuntimeException(
 256  
                     "Collection group id to update for inactive record display not found in request");
 257  
         }
 258  
 
 259  0
         String showInactiveStr = request.getParameter(UifParameters.SHOW_INACTIVE_RECORDS);
 260  0
         Boolean showInactive = false;
 261  0
         if (StringUtils.isNotBlank(showInactiveStr)) {
 262  
             // TODO: should use property editors once we have util class
 263  0
             showInactive = (Boolean) (new BooleanFormatter()).convertFromPresentationFormat(showInactiveStr);
 264  
         } else {
 265  0
             throw new RuntimeException("Show inactive records flag not found in request");
 266  
         }
 267  
 
 268  0
         CollectionGroup collectionGroup = (CollectionGroup) ComponentFactory.getNewInstanceForRefresh(uifForm.getView(),
 269  
                 collectionGroupId);
 270  
 
 271  
         // update inactive flag on group
 272  0
         collectionGroup.setShowInactive(showInactive);
 273  
 
 274  
         // run lifecycle and update in view
 275  0
         uifForm.getView().getViewHelperService().performComponentLifecycle(uifForm.getView(), uifForm, collectionGroup,
 276  
                 collectionGroupId);
 277  
 
 278  0
         return UifWebUtils.getComponentModelAndView(collectionGroup, uifForm);
 279  
     }
 280  
 
 281  
     /**
 282  
      * Just returns as if return with no value was selected.
 283  
      */
 284  
     @RequestMapping(params = "methodToCall=cancel")
 285  
     public ModelAndView cancel(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
 286  
             HttpServletRequest request, HttpServletResponse response) {
 287  0
         return close(form, result, request, response);
 288  
     }
 289  
 
 290  
     /**
 291  
      * Just returns as if return with no value was selected.
 292  
      */
 293  
     @RequestMapping(params = "methodToCall=close")
 294  
     public ModelAndView close(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
 295  
             HttpServletRequest request, HttpServletResponse response) {
 296  0
         Properties props = new Properties();
 297  0
         props.put(UifParameters.METHOD_TO_CALL, UifConstants.MethodToCallNames.REFRESH);
 298  0
         if (StringUtils.isNotBlank(form.getReturnFormKey())) {
 299  0
             props.put(UifParameters.FORM_KEY, form.getReturnFormKey());
 300  
         }
 301  
 
 302  
         // TODO this needs setup for lightbox and possible home location
 303  
         // property
 304  0
         String returnUrl = form.getReturnLocation();
 305  0
         if (StringUtils.isBlank(returnUrl)) {
 306  0
             returnUrl = ConfigContext.getCurrentContextConfig().getProperty(KRADConstants.APPLICATION_URL_KEY);
 307  
         }
 308  
 
 309  0
         return performRedirect(form, returnUrl, props);
 310  
     }
 311  
 
 312  
     /**
 313  
      * Invoked to navigate back one page in history..
 314  
      *
 315  
      * @param form - form object that should contain the history object
 316  
      */
 317  
     @RequestMapping(params = "methodToCall=returnToPrevious")
 318  
     public ModelAndView returnToPrevious(@ModelAttribute("KualiForm") UifFormBase form) {
 319  
 
 320  0
         return returnToHistory(form, false);
 321  
     }
 322  
 
 323  
     /**
 324  
      * Invoked to navigate back to the first page in history.
 325  
      *
 326  
      * @param form - form object that should contain the history object
 327  
      */
 328  
     @RequestMapping(params = "methodToCall=returnToHub")
 329  
     public ModelAndView returnToHub(@ModelAttribute("KualiForm") UifFormBase form) {
 330  
 
 331  0
         return returnToHistory(form, true);
 332  
     }
 333  
 
 334  
     /**
 335  
      * Invoked to navigate back to a history entry. The homeFlag will determine whether navigation
 336  
      * will be back to the first or last history entry.
 337  
      *
 338  
      * @param form - form object that should contain the history object
 339  
      * @param homeFlag - if true will navigate back to first entry else will navigate to last entry
 340  
      * in the history
 341  
      */
 342  
     public ModelAndView returnToHistory(UifFormBase form, boolean homeFlag) {
 343  
         // Get the history from the form
 344  0
         History hist = form.getFormHistory();
 345  0
         List<HistoryEntry> histEntries = hist.getHistoryEntries();
 346  
 
 347  
         // Get the history page url. Default to the application url if there is no history.
 348  0
         String histUrl = null;
 349  0
         if (histEntries.isEmpty()) {
 350  0
             histUrl = ConfigContext.getCurrentContextConfig().getProperty(KRADConstants.APPLICATION_URL_KEY);
 351  
         } else {
 352  
             // For home get the first entry, for previous get the last entry.
 353  
             // Remove history up to where page is opened
 354  0
             if (homeFlag) {
 355  0
                 histUrl = histEntries.get(0).getUrl();
 356  0
                 histEntries.clear();
 357  
             } else {
 358  0
                 histUrl = histEntries.get(histEntries.size() - 1).getUrl();
 359  0
                 histEntries.remove(histEntries.size() - 1);
 360  0
                 hist.setCurrent(null);
 361  
             }
 362  
         }
 363  
 
 364  
         // Add the refresh call
 365  0
         Properties props = new Properties();
 366  0
         props.put(UifParameters.METHOD_TO_CALL, UifConstants.MethodToCallNames.REFRESH);
 367  
 
 368  0
         return performRedirect(form, histUrl, props);
 369  
     }
 370  
 
 371  
     /**
 372  
      * Handles menu navigation between view pages
 373  
      */
 374  
     @RequestMapping(method = RequestMethod.POST, params = "methodToCall=navigate")
 375  
     public ModelAndView navigate(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
 376  
             HttpServletRequest request, HttpServletResponse response) {
 377  0
         String pageId = form.getActionParamaterValue(UifParameters.NAVIGATE_TO_PAGE_ID);
 378  
 
 379  
         // only refreshing page
 380  0
         form.setRenderFullView(false);
 381  
 
 382  0
         return getUIFModelAndView(form, pageId);
 383  
     }
 384  
 
 385  
     @RequestMapping(params = "methodToCall=refresh")
 386  
     public ModelAndView refresh(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
 387  
             HttpServletRequest request, HttpServletResponse response) throws Exception {
 388  
         // TODO: this code still needs to handle reference refreshes
 389  0
         String refreshCallerType = "";
 390  0
         if (request.getParameterMap().containsKey(KRADConstants.REFRESH_CALLER_TYPE)) {
 391  0
             refreshCallerType = request.getParameter(KRADConstants.REFRESH_CALLER_TYPE);
 392  
         }
 393  
 
 394  
         // process multi-value lookup returns
 395  0
         if (StringUtils.equals(refreshCallerType, UifConstants.RefreshCallerTypes.MULTI_VALUE_LOOKUP)) {
 396  0
             String lookupCollectionName = "";
 397  0
             if (request.getParameterMap().containsKey(UifParameters.LOOKUP_COLLECTION_NAME)) {
 398  0
                 lookupCollectionName = request.getParameter(UifParameters.LOOKUP_COLLECTION_NAME);
 399  
             }
 400  
 
 401  0
             if (StringUtils.isBlank(lookupCollectionName)) {
 402  0
                 throw new RuntimeException(
 403  
                         "Lookup collection name is required for processing multi-value lookup results");
 404  
             }
 405  
 
 406  0
             String selectedLineValues = "";
 407  0
             if (request.getParameterMap().containsKey(UifParameters.SELECTED_LINE_VALUES)) {
 408  0
                 selectedLineValues = request.getParameter(UifParameters.SELECTED_LINE_VALUES);
 409  
             }
 410  
 
 411  
             // invoked view helper to populate the collection from lookup results
 412  0
             form.getPreviousView().getViewHelperService().processMultipleValueLookupResults(form.getPreviousView(),
 413  
                     form, lookupCollectionName, selectedLineValues);
 414  
         }
 415  
 
 416  0
         form.setRenderFullView(true);
 417  
 
 418  0
         return getUIFModelAndView(form);
 419  
     }
 420  
 
 421  
     /**
 422  
      * Updates the current component by retrieving a fresh copy from the dictionary,
 423  
      * running its component lifecycle, and returning it
 424  
      *
 425  
      * @param request - the request must contain reqComponentId that specifies the component to retrieve
 426  
      */
 427  
     @RequestMapping(method = RequestMethod.POST, params = "methodToCall=updateComponent")
 428  
     public ModelAndView updateComponent(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
 429  
             HttpServletRequest request, HttpServletResponse response) {
 430  0
         String requestedComponentId = request.getParameter(UifParameters.REQUESTED_COMPONENT_ID);
 431  0
         if (StringUtils.isBlank(requestedComponentId)) {
 432  0
             throw new RuntimeException("Requested component id for update not found in request");
 433  
         }
 434  
 
 435  
         // get a new instance of the component
 436  0
         Component comp = ComponentFactory.getNewInstanceForRefresh(form.getView(), requestedComponentId);
 437  
 
 438  
         // run lifecycle and update in view
 439  0
         form.getView().getViewHelperService().performComponentLifecycle(form.getView(), form, comp,
 440  
                 requestedComponentId);
 441  
 
 442  0
         return UifWebUtils.getComponentModelAndView(comp, form);
 443  
     }
 444  
 
 445  
     /**
 446  
      * Builds up a URL to the lookup view based on the given post action
 447  
      * parameters and redirects
 448  
      */
 449  
     @RequestMapping(method = RequestMethod.POST, params = "methodToCall=performLookup")
 450  
     public ModelAndView performLookup(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
 451  
             HttpServletRequest request, HttpServletResponse response) {
 452  0
         Properties lookupParameters = form.getActionParametersAsProperties();
 453  
 
 454  0
         String lookupObjectClassName = (String) lookupParameters.get(UifParameters.DATA_OBJECT_CLASS_NAME);
 455  0
         Class<?> lookupObjectClass = null;
 456  
         try {
 457  0
             lookupObjectClass = Class.forName(lookupObjectClassName);
 458  0
         } catch (ClassNotFoundException e) {
 459  0
             LOG.error("Unable to get class for name: " + lookupObjectClassName);
 460  0
             throw new RuntimeException("Unable to get class for name: " + lookupObjectClassName, e);
 461  0
         }
 462  
 
 463  
         // get form values for the lookup parameter fields
 464  0
         String lookupParameterString = (String) lookupParameters.get(UifParameters.LOOKUP_PARAMETERS);
 465  0
         if (lookupParameterString != null) {
 466  0
             Map<String, String> lookupParameterFields = KRADUtils.getMapFromParameterString(lookupParameterString);
 467  0
             for (Entry<String, String> lookupParameter : lookupParameterFields.entrySet()) {
 468  0
                 String lookupParameterValue = LookupInquiryUtils.retrieveLookupParameterValue(form, request,
 469  
                         lookupObjectClass, lookupParameter.getValue(), lookupParameter.getKey());
 470  
 
 471  0
                 if (StringUtils.isNotBlank(lookupParameterValue)) {
 472  0
                     lookupParameters.put(UifPropertyPaths.CRITERIA_FIELDS + "['" + lookupParameter.getValue() + "']",
 473  
                             lookupParameterValue);
 474  
                 }
 475  0
             }
 476  
         }
 477  
 
 478  
         // TODO: lookup anchors and doc number?
 479  
 
 480  0
         String baseLookupUrl = (String) lookupParameters.get(UifParameters.BASE_LOOKUP_URL);
 481  0
         lookupParameters.remove(UifParameters.BASE_LOOKUP_URL);
 482  
 
 483  
         // set lookup method to call
 484  0
         lookupParameters.put(UifParameters.METHOD_TO_CALL, UifConstants.MethodToCallNames.START);
 485  0
         String autoSearchString = (String) lookupParameters.get(UifParameters.AUTO_SEARCH);
 486  0
         if (Boolean.parseBoolean(autoSearchString)) {
 487  0
             lookupParameters.put(UifParameters.METHOD_TO_CALL, UifConstants.MethodToCallNames.SEARCH);
 488  
         }
 489  
 
 490  0
         lookupParameters.put(UifParameters.RETURN_LOCATION, form.getFormPostUrl());
 491  0
         lookupParameters.put(UifParameters.RETURN_FORM_KEY, form.getFormKey());
 492  
 
 493  
         // special check for external object classes
 494  0
         if (lookupObjectClass != null) {
 495  0
             ModuleService responsibleModuleService =
 496  
                     KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(lookupObjectClass);
 497  0
             if (responsibleModuleService != null && responsibleModuleService.isExternalizable(lookupObjectClass)) {
 498  0
                 Class<? extends ExternalizableBusinessObject> implLookupObjectClass =
 499  
                         responsibleModuleService.getExternalizableBusinessObjectImplementation(
 500  
                                 lookupObjectClass.asSubclass(ExternalizableBusinessObject.class));
 501  
 
 502  0
                 if (implLookupObjectClass != null) {
 503  0
                     lookupParameters.put(UifParameters.DATA_OBJECT_CLASS_NAME, implLookupObjectClass.getName());
 504  
                 } else {
 505  0
                     throw new RuntimeException(
 506  
                             "Unable to find implementation class for EBO: " + lookupObjectClass.getName());
 507  
                 }
 508  
 
 509  
                 // TODO: should call module service to get full URL, but right now it is coded to direct to the KNS lookups
 510  
                 //                Map<String, String> parameterMap = new HashMap<String, String>();
 511  
                 //                Enumeration<Object> e = lookupParameters.keys();
 512  
                 //                while (e.hasMoreElements()) {
 513  
                 //                    String paramName = (String) e.nextElement();
 514  
                 //                    parameterMap.put(paramName, lookupParameters.getProperty(paramName));
 515  
                 //                }
 516  
                 //
 517  
                 //                String lookupUrl = responsibleModuleService.getExternalizableBusinessObjectLookupUrl(lookupObjectClass,
 518  
                 //                        parameterMap);
 519  
                 //                return performRedirect(form, lookupUrl, new Properties());
 520  
             }
 521  
         }
 522  
 
 523  0
         return performRedirect(form, baseLookupUrl, lookupParameters);
 524  
     }
 525  
 
 526  
     /**
 527  
      * Invoked to provide the options for a suggest widget. The valid options are retrieved by the associated
 528  
      * <code>AttributeQuery</code> for the field containing the suggest widget. The controller method picks
 529  
      * out the query parameters from the request and calls <code>AttributeQueryService</code> to perform the
 530  
      * suggest query and prepare the result object that will be exposed with JSON
 531  
      */
 532  
     @RequestMapping(method = RequestMethod.GET, params = "methodToCall=performFieldSuggest")
 533  
     public
 534  
     @ResponseBody
 535  
     AttributeQueryResult performFieldSuggest(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
 536  
             HttpServletRequest request, HttpServletResponse response) {
 537  
 
 538  
         // retrieve query fields from request
 539  0
         Map<String, String> queryParameters = new HashMap<String, String>();
 540  0
         for (Object parameterName : request.getParameterMap().keySet()) {
 541  0
             if (parameterName.toString().startsWith(UifParameters.QUERY_PARAMETER + ".")) {
 542  0
                 String fieldName = StringUtils.substringAfter(parameterName.toString(),
 543  
                         UifParameters.QUERY_PARAMETER + ".");
 544  0
                 String fieldValue = request.getParameter(parameterName.toString());
 545  0
                 queryParameters.put(fieldName, fieldValue);
 546  0
             }
 547  
         }
 548  
 
 549  
         // retrieve id for field to perform query for
 550  0
         String queryFieldId = request.getParameter(UifParameters.QUERY_FIELD_ID);
 551  0
         if (StringUtils.isBlank(queryFieldId)) {
 552  0
             throw new RuntimeException("Unable to find id for field to perform query on under request parameter name: "
 553  
                     + UifParameters.QUERY_FIELD_ID);
 554  
         }
 555  
 
 556  
         // get the field term to match
 557  0
         String queryTerm = request.getParameter(UifParameters.QUERY_TERM);
 558  0
         if (StringUtils.isBlank(queryTerm)) {
 559  0
             throw new RuntimeException(
 560  
                     "Unable to find id for query term value for attribute query on under request parameter name: "
 561  
                             + UifParameters.QUERY_TERM);
 562  
         }
 563  
 
 564  
         // invoke attribute query service to perform the query
 565  0
         AttributeQueryResult queryResult = KRADServiceLocatorWeb.getAttributeQueryService().performFieldSuggestQuery(
 566  
                 form.getView(), queryFieldId, queryTerm, queryParameters);
 567  
 
 568  0
         return queryResult;
 569  
     }
 570  
 
 571  
     /**
 572  
      * Invoked to execute the <code>AttributeQuery</code> associated with a field given the query parameters
 573  
      * found in the request. This controller method picks out the query parameters from the request and calls
 574  
      * <code>AttributeQueryService</code> to perform the field query and prepare the result object
 575  
      * that will be exposed with JSON. The result is then used to update field values in the UI with client
 576  
      * script.
 577  
      */
 578  
     @RequestMapping(method = RequestMethod.GET, params = "methodToCall=performFieldQuery")
 579  
     public
 580  
     @ResponseBody
 581  
     AttributeQueryResult performFieldQuery(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
 582  
             HttpServletRequest request, HttpServletResponse response) {
 583  
 
 584  
         // retrieve query fields from request
 585  0
         Map<String, String> queryParameters = new HashMap<String, String>();
 586  0
         for (Object parameterName : request.getParameterMap().keySet()) {
 587  0
             if (parameterName.toString().startsWith(UifParameters.QUERY_PARAMETER + ".")) {
 588  0
                 String fieldName = StringUtils.substringAfter(parameterName.toString(),
 589  
                         UifParameters.QUERY_PARAMETER + ".");
 590  0
                 String fieldValue = request.getParameter(parameterName.toString());
 591  0
                 queryParameters.put(fieldName, fieldValue);
 592  0
             }
 593  
         }
 594  
 
 595  
         // retrieve id for field to perform query for
 596  0
         String queryFieldId = request.getParameter(UifParameters.QUERY_FIELD_ID);
 597  0
         if (StringUtils.isBlank(queryFieldId)) {
 598  0
             throw new RuntimeException("Unable to find id for field to perform query on under request parameter name: "
 599  
                     + UifParameters.QUERY_FIELD_ID);
 600  
         }
 601  
 
 602  
         // invoke attribute query service to perform the query
 603  0
         AttributeQueryResult queryResult = KRADServiceLocatorWeb.getAttributeQueryService().performFieldQuery(
 604  
                 form.getView(), queryFieldId, queryParameters);
 605  
 
 606  0
         return queryResult;
 607  
     }
 608  
 
 609  
     /**
 610  
      * Builds a <code>ModelAndView</code> instance configured to redirect to the
 611  
      * URL formed by joining the base URL with the given URL parameters
 612  
      *
 613  
      * @param form - current form instance
 614  
      * @param baseUrl - base url to redirect to
 615  
      * @param urlParameters - properties containing key/value pairs for the url parameters
 616  
      * @return ModelAndView configured to redirect to the given URL
 617  
      */
 618  
     protected ModelAndView performRedirect(UifFormBase form, String baseUrl, Properties urlParameters) {
 619  
         // since we are redirecting and will not be rendering the view, we need to reset the view from the previous
 620  0
         form.setView(form.getPreviousView());
 621  
 
 622  
         // On post redirects we need to make sure we are sending the history forward:
 623  0
         urlParameters.setProperty(UifConstants.UrlParams.HISTORY, form.getFormHistory().getHistoryParameterString());
 624  
 
 625  
         // If this is an Light Box call only return the redirectURL view with the URL
 626  
         // set this is to avoid automatic redirect when using light boxes
 627  0
         if (urlParameters.get(UifParameters.LIGHTBOX_CALL) != null &&
 628  
                 urlParameters.get(UifParameters.LIGHTBOX_CALL).equals("true")) {
 629  0
             urlParameters.remove(UifParameters.LIGHTBOX_CALL);
 630  0
             String redirectUrl = UrlFactory.parameterizeUrl(baseUrl, urlParameters);
 631  
 
 632  0
             ModelAndView modelAndView = new ModelAndView(UifConstants.SPRING_REDIRECT_ID);
 633  0
             modelAndView.addObject("redirectUrl", redirectUrl);
 634  0
             return modelAndView;
 635  
         }
 636  
 
 637  0
         String redirectUrl = UrlFactory.parameterizeUrl(baseUrl, urlParameters);
 638  0
         ModelAndView modelAndView = new ModelAndView(REDIRECT_PREFIX + redirectUrl);
 639  
 
 640  0
         return modelAndView;
 641  
     }
 642  
 
 643  
     protected ModelAndView getUIFModelAndView(UifFormBase form) {
 644  0
         return getUIFModelAndView(form, form.getPageId());
 645  
     }
 646  
 
 647  
     /**
 648  
      * Configures the <code>ModelAndView</code> instance containing the form
 649  
      * data and pointing to the UIF generic spring view
 650  
      *
 651  
      * @param form - Form instance containing the model data
 652  
      * @param pageId - Id of the page within the view that should be rendered, can
 653  
      * be left blank in which the current or default page is rendered
 654  
      * @return ModelAndView object with the contained form
 655  
      */
 656  
     protected ModelAndView getUIFModelAndView(UifFormBase form, String pageId) {
 657  0
         return UifWebUtils.getUIFModelAndView(form, pageId);
 658  
     }
 659  
 
 660  
     protected ViewService getViewService() {
 661  0
         return KRADServiceLocatorWeb.getViewService();
 662  
     }
 663  
 
 664  
     public SessionDocumentService getSessionDocumentService() {
 665  0
         return KRADServiceLocatorWeb.getSessionDocumentService();
 666  
     }
 667  
 
 668  
 }