Coverage Report - org.kuali.rice.kns.web.struts.action.KualiAction
 
Classes in this File Line Coverage Branch Coverage Complexity
KualiAction
0%
0/393
0%
0/228
4.263
 
 1  
 /*
 2  
  * Copyright 2005-2007 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.kns.web.struts.action;
 17  
 
 18  
 import java.util.Arrays;
 19  
 import java.util.Enumeration;
 20  
 import java.util.HashMap;
 21  
 import java.util.HashSet;
 22  
 import java.util.Map;
 23  
 import java.util.Properties;
 24  
 import java.util.Set;
 25  
 
 26  
 import javax.servlet.http.HttpServletRequest;
 27  
 import javax.servlet.http.HttpServletResponse;
 28  
 
 29  
 import org.apache.commons.lang.ObjectUtils;
 30  
 import org.apache.commons.lang.StringUtils;
 31  
 import org.apache.log4j.Level;
 32  
 import org.apache.struts.action.ActionForm;
 33  
 import org.apache.struts.action.ActionForward;
 34  
 import org.apache.struts.action.ActionMapping;
 35  
 import org.apache.struts.actions.DispatchAction;
 36  
 import org.kuali.rice.core.service.Demonstration;
 37  
 import org.kuali.rice.core.service.EncryptionService;
 38  
 import org.kuali.rice.core.util.RiceConstants;
 39  
 import org.kuali.rice.kim.bo.types.dto.AttributeSet;
 40  
 import org.kuali.rice.kim.service.KIMServiceLocator;
 41  
 import org.kuali.rice.kim.util.KimCommonUtils;
 42  
 import org.kuali.rice.kim.util.KimConstants;
 43  
 import org.kuali.rice.kns.bo.BusinessObject;
 44  
 import org.kuali.rice.kns.document.authorization.DocumentAuthorizerBase;
 45  
 import org.kuali.rice.kns.exception.AuthorizationException;
 46  
 import org.kuali.rice.kns.lookup.LookupUtils;
 47  
 import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
 48  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 49  
 import org.kuali.rice.kns.service.KualiModuleService;
 50  
 import org.kuali.rice.kns.service.ModuleService;
 51  
 import org.kuali.rice.kns.util.GlobalVariables;
 52  
 import org.kuali.rice.kns.util.KNSConstants;
 53  
 import org.kuali.rice.kns.util.UrlFactory;
 54  
 import org.kuali.rice.kns.util.WebUtils;
 55  
 import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
 56  
 import org.kuali.rice.kns.web.struts.form.KualiForm;
 57  
 import org.kuali.rice.kns.web.struts.form.LookupForm;
 58  
 import org.kuali.rice.kns.web.struts.pojo.PojoForm;
 59  
 import org.kuali.rice.kns.web.struts.pojo.PojoFormBase;
 60  
 
 61  
 /**
 62  
  * This class is the base action class for all kuali actions. Overrides execute to set methodToCall for image submits. Other setup
 63  
  * for framework calls.
 64  
  *
 65  
  *
 66  
  */
 67  
 /**
 68  
  * This is a description of what this class does - ctdang don't forget to fill this in. 
 69  
  * 
 70  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 71  
  *
 72  
  */
 73  0
 public abstract class KualiAction extends DispatchAction {
 74  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiAction.class);
 75  
 
 76  0
     private static KualiModuleService kualiModuleService = null;
 77  0
     private static BusinessObjectAuthorizationService businessObjectAuthorizationService = null;
 78  0
     private static EncryptionService encryptionService = null;
 79  0
     private static Boolean OUTPUT_ENCRYPTION_WARNING = null;
 80  0
     private static String applicationBaseUrl = null;
 81  
     
 82  0
     private Set<String> methodToCallsToNotCheckAuthorization = new HashSet<String>();
 83  
     
 84  
     {
 85  0
             methodToCallsToNotCheckAuthorization.add( "performLookup" );
 86  0
             methodToCallsToNotCheckAuthorization.add( "performQuestion" );
 87  0
             methodToCallsToNotCheckAuthorization.add( "performQuestionWithInput" );
 88  0
             methodToCallsToNotCheckAuthorization.add( "performQuestionWithInputAgainBecauseOfErrors" );
 89  0
             methodToCallsToNotCheckAuthorization.add( "performQuestionWithoutInput" );
 90  0
             methodToCallsToNotCheckAuthorization.add( "performWorkgroupLookup" );
 91  0
     }
 92  
     
 93  
     /**
 94  
      * Entry point to all actions.
 95  
      *
 96  
      * NOTE: No need to hook into execute for handling framwork setup anymore. Just implement the methodToCall for the framework
 97  
      * setup, Constants.METHOD_REQUEST_PARAMETER will contain the full parameter, which can be sub stringed for getting framework
 98  
      * parameters.
 99  
      *
 100  
      * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm,
 101  
      *      javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
 102  
      */
 103  
     public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 104  0
         ActionForward returnForward = null;
 105  
 
 106  0
         String methodToCall = findMethodToCall(form, request);
 107  0
         if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getMethodToCall())) {
 108  0
             if (StringUtils.isNotBlank(getImageContext(request, KNSConstants.ANCHOR))) {
 109  0
                 ((KualiForm) form).setAnchor(getImageContext(request, KNSConstants.ANCHOR));
 110  
             }
 111  0
             else if (StringUtils.isNotBlank(request.getParameter(KNSConstants.ANCHOR))) {
 112  0
                 ((KualiForm) form).setAnchor(request.getParameter(KNSConstants.ANCHOR));
 113  
             }
 114  
             else {
 115  0
                 ((KualiForm) form).setAnchor(KNSConstants.ANCHOR_TOP_OF_FORM);
 116  
             }
 117  
         }
 118  
         // if found methodToCall, pass control to that method, else return the basic forward
 119  0
         if (StringUtils.isNotBlank(methodToCall)) {
 120  0
                 if ( LOG.isDebugEnabled() ) {
 121  0
                         LOG.debug("methodToCall: '" + methodToCall+"'");
 122  
                 }
 123  0
             returnForward = dispatchMethod(mapping, form, request, response, methodToCall);
 124  
         }
 125  
         else {
 126  0
             returnForward = defaultDispatch(mapping, form, request, response);
 127  
         }
 128  
 
 129  
         // make sure the user can do what they're trying to according to the module that owns the functionality
 130  0
         if ( !methodToCallsToNotCheckAuthorization.contains(methodToCall) ) {
 131  0
                 if ( LOG.isDebugEnabled() ) {
 132  0
                         LOG.debug( "'" + methodToCall + "' not in set of excempt methods: " + methodToCallsToNotCheckAuthorization);
 133  
                 }
 134  0
                 checkAuthorization(form, methodToCall);
 135  
         } else {
 136  0
                 if ( LOG.isDebugEnabled() ) {
 137  0
                         LOG.debug("'" + methodToCall + "' is exempt from auth checks." );
 138  
                 }
 139  
         }
 140  
 
 141  
         // check if demonstration encryption is enabled
 142  0
         if ( LOG.isEnabledFor(Level.WARN) ) {
 143  0
                 if ( OUTPUT_ENCRYPTION_WARNING == null ) {
 144  0
                         OUTPUT_ENCRYPTION_WARNING = KNSServiceLocator.getParameterService().getIndicatorParameter(KNSConstants.KNS_NAMESPACE, KNSConstants.DetailTypes.ALL_DETAIL_TYPE, KNSConstants.SystemGroupParameterNames.CHECK_ENCRYPTION_SERVICE_OVERRIDE_IND) && KNSServiceLocator.getEncryptionService() instanceof Demonstration; 
 145  
                 }
 146  0
                 if ( OUTPUT_ENCRYPTION_WARNING.booleanValue() ) {
 147  0
                     LOG.warn("WARNING: This implementation of Kuali uses the demonstration encryption framework.");
 148  
                 }
 149  
         }
 150  
 
 151  
         // Add the ActionForm to GlobalVariables
 152  
         // This will allow developers to retrieve both the Document and any request parameters that are not
 153  
         // part of the Form and make them available in ValueFinder classes and other places where they are needed.
 154  0
         if(GlobalVariables.getKualiForm() == null) {
 155  0
                 GlobalVariables.setKualiForm((KualiForm)form);
 156  
         }
 157  
 
 158  0
         return returnForward;
 159  
     }
 160  
     
 161  
     /**
 162  
      * When no methodToCall is specified, the defaultDispatch method is invoked.  Default implementation
 163  
      * returns the "basic" ActionForward.
 164  
      */
 165  
     protected ActionForward defaultDispatch(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 166  0
             return mapping.findForward(RiceConstants.MAPPING_BASIC);
 167  
     }
 168  
 
 169  
     @Override
 170  
     protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String methodToCall) throws Exception {
 171  0
         GlobalVariables.getUserSession().addObject(DocumentAuthorizerBase.USER_SESSION_METHOD_TO_CALL_OBJECT_KEY, (Object)methodToCall);
 172  0
         return super.dispatchMethod(mapping, form, request, response, methodToCall);
 173  
     }
 174  
     
 175  
     protected String findMethodToCall(ActionForm form, HttpServletRequest request) throws Exception {
 176  
         String methodToCall;
 177  0
         if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getMethodToCall())) {
 178  0
             methodToCall = ((KualiForm) form).getMethodToCall();
 179  
         }
 180  
         else {
 181  
             // call utility method to parse the methodToCall from the request.
 182  0
             methodToCall = WebUtils.parseMethodToCall(form, request);
 183  
         }
 184  0
         return methodToCall;
 185  
     }
 186  
 
 187  
     /**
 188  
      * Toggles the tab state in the ui
 189  
      *
 190  
      * @param mapping
 191  
      * @param form
 192  
      * @param request
 193  
      * @param response
 194  
      * @return
 195  
      * @throws Exception
 196  
      */
 197  
     public ActionForward toggleTab(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 198  0
         KualiForm kualiForm = (KualiForm) form;
 199  0
         String tabToToggle = getTabToToggle(request);
 200  0
         if (StringUtils.isNotBlank(tabToToggle)) {
 201  0
             if (kualiForm.getTabState(tabToToggle).equals("OPEN")) {
 202  0
                     kualiForm.getTabStates().remove(tabToToggle);
 203  0
                     kualiForm.getTabStates().put(tabToToggle, "CLOSE");
 204  
             }
 205  
             else {
 206  0
                     kualiForm.getTabStates().remove(tabToToggle);
 207  0
                     kualiForm.getTabStates().put(tabToToggle, "OPEN");
 208  
             }
 209  
         }
 210  
 
 211  0
         doProcessingAfterPost( kualiForm, request );
 212  0
         return mapping.findForward(RiceConstants.MAPPING_BASIC);
 213  
     }
 214  
 
 215  
     /**
 216  
      * Toggles all tabs to open
 217  
      *
 218  
      * @param mapping
 219  
      * @param form
 220  
      * @param request
 221  
      * @param response
 222  
      * @return
 223  
      * @throws Exception
 224  
      */
 225  
     public ActionForward showAllTabs(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 226  0
             return this.doTabOpenOrClose(mapping, form, request, response, true);
 227  
     }
 228  
 
 229  
     /**
 230  
      * Toggles all tabs to closed
 231  
      *
 232  
      * @param mapping
 233  
      * @param form
 234  
      * @param request
 235  
      * @param response
 236  
      * @return
 237  
      * @throws Exception
 238  
      */
 239  
     public ActionForward hideAllTabs(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 240  0
         return this.doTabOpenOrClose(mapping, form, request, response, false);
 241  
     }
 242  
     
 243  
     /**
 244  
      * 
 245  
      * Toggles all tabs to open of closed depending on the boolean flag.
 246  
      * 
 247  
      * @param mapping the mapping
 248  
      * @param form the form
 249  
      * @param request the request
 250  
      * @param response the response
 251  
      * @param open whether to open of close the tabs
 252  
      * @return the action forward
 253  
      */
 254  
     private ActionForward doTabOpenOrClose(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, boolean open) {
 255  0
         KualiForm kualiForm = (KualiForm) form;
 256  
 
 257  0
         Map<String, String> tabStates = kualiForm.getTabStates();
 258  0
         Map<String, String> newTabStates = new HashMap<String, String>();
 259  0
         for (String tabKey: tabStates.keySet()) {
 260  0
                 newTabStates.put(tabKey, open ? "OPEN" : "CLOSE");
 261  
         }
 262  0
         kualiForm.setTabStates(newTabStates);
 263  0
         doProcessingAfterPost( kualiForm, request );
 264  0
         return mapping.findForward(RiceConstants.MAPPING_BASIC);
 265  
     }
 266  
 
 267  
     /**
 268  
      * Default refresh method. Called from returning frameworks.
 269  
      *
 270  
      * @param mapping
 271  
      * @param form
 272  
      * @param request
 273  
      * @param response
 274  
      * @return
 275  
      * @throws Exception
 276  
      */
 277  
     public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 278  0
         return mapping.findForward(RiceConstants.MAPPING_BASIC);
 279  
     }
 280  
 
 281  
 
 282  
     /**
 283  
      * Parses the method to call attribute to pick off the line number which should be deleted.
 284  
      *
 285  
      * @param request
 286  
      * @return
 287  
      */
 288  
     protected int getLineToDelete(HttpServletRequest request) {
 289  0
         return getSelectedLine(request);
 290  
     }
 291  
 
 292  
     /**
 293  
      * Parses the method to call attribute to pick off the line number which should have an action performed on it.
 294  
      *
 295  
      * @param request
 296  
      * @return
 297  
      */
 298  
     protected int getSelectedLine(HttpServletRequest request) {
 299  0
         int selectedLine = -1;
 300  0
         String parameterName = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 301  0
         if (StringUtils.isNotBlank(parameterName)) {
 302  0
             String lineNumber = StringUtils.substringBetween(parameterName, ".line", ".");
 303  0
             selectedLine = Integer.parseInt(lineNumber);
 304  
         }
 305  
 
 306  0
         return selectedLine;
 307  
     }
 308  
 
 309  
     /**
 310  
      * Determines which tab was requested to be toggled
 311  
      *
 312  
      * @param request
 313  
      * @return
 314  
      */
 315  
     protected String getTabToToggle(HttpServletRequest request) {
 316  0
         String tabToToggle = "";
 317  0
         String parameterName = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 318  0
         if (StringUtils.isNotBlank(parameterName)) {
 319  0
             tabToToggle = StringUtils.substringBetween(parameterName, ".tab", ".");
 320  
         }
 321  
 
 322  0
         return tabToToggle;
 323  
     }
 324  
 
 325  
     /**
 326  
      * Retrieves the header tab to navigate to.
 327  
      *
 328  
      * @param request
 329  
      * @return
 330  
      */
 331  
     protected String getHeaderTabNavigateTo(HttpServletRequest request) {
 332  0
         String headerTabNavigateTo = RiceConstants.MAPPING_BASIC;
 333  0
         String imageContext = getImageContext(request, KNSConstants.NAVIGATE_TO);
 334  0
         if (StringUtils.isNotBlank(imageContext)) {
 335  0
             headerTabNavigateTo = imageContext;
 336  
         }
 337  0
         return headerTabNavigateTo;
 338  
     }
 339  
 
 340  
     /**
 341  
      * Retrieves the header tab dispatch.
 342  
      *
 343  
      * @param request
 344  
      * @return
 345  
      */
 346  
     protected String getHeaderTabDispatch(HttpServletRequest request) {
 347  0
         String headerTabDispatch = null;
 348  0
         String imageContext = getImageContext(request, KNSConstants.HEADER_DISPATCH);
 349  0
         if (StringUtils.isNotBlank(imageContext)) {
 350  0
             headerTabDispatch = imageContext;
 351  
         }
 352  
         else {
 353  
             // In some cases it might be in request params instead
 354  0
             headerTabDispatch = request.getParameter(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 355  
         }
 356  0
         return headerTabDispatch;
 357  
     }
 358  
 
 359  
     /**
 360  
      * Retrieves the image context
 361  
      *
 362  
      * @param request
 363  
      * @param contextKey
 364  
      * @return
 365  
      */
 366  
     protected String getImageContext(HttpServletRequest request, String contextKey) {
 367  0
         String imageContext = "";
 368  0
         String parameterName = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 369  0
         if (StringUtils.isBlank(parameterName)) {
 370  0
             parameterName = request.getParameter("methodToCallPath");
 371  
         }
 372  0
         if (StringUtils.isNotBlank(parameterName)) {
 373  0
             imageContext = StringUtils.substringBetween(parameterName, contextKey, ".");
 374  
         }
 375  0
         return imageContext;
 376  
     }
 377  
 
 378  
     protected String getReturnLocation(HttpServletRequest request, ActionMapping mapping) {
 379  0
             String mappingPath = mapping.getPath();
 380  0
             String basePath = getApplicationBaseUrl();
 381  0
         return basePath + ("/lookup".equals(mappingPath) || "/maintenance".equals(mappingPath) || "/multipleValueLookup".equals(mappingPath) ? "/kr" : "") + mappingPath + ".do";
 382  
     }
 383  
 
 384  
     /**
 385  
      * Retrieves the value of a parameter to be passed into the lookup or inquiry frameworks.  The default implementation of this method will attempt to look
 386  
      * in the request to determine wheter the appropriate value exists as a request parameter.  If not, it will attempt to look through the form object to find
 387  
      * the property.
 388  
      * 
 389  
      * @param boClass a class implementing boClass, representing the BO that will be looked up
 390  
      * @param parameterName the name of the parameter
 391  
      * @param parameterValuePropertyName the property (relative to the form object) where the value to be passed into the lookup/inquiry may be found
 392  
      * @param form
 393  
      * @param request
 394  
      * @return
 395  
      */
 396  
     protected String retrieveLookupParameterValue(Class<? extends BusinessObject> boClass, String parameterName, String parameterValuePropertyName, ActionForm form, HttpServletRequest request) throws Exception {
 397  
             String value;
 398  0
             if (StringUtils.contains(parameterValuePropertyName, "'")) {
 399  0
                     value = StringUtils.replace(parameterValuePropertyName, "'", "");
 400  
             }
 401  0
             else if (request.getParameterMap().containsKey(parameterValuePropertyName)) {
 402  0
                     value = request.getParameter(parameterValuePropertyName);
 403  
             }
 404  
             else {
 405  0
                     if (form instanceof KualiForm) {
 406  0
                             value = ((KualiForm) form).retrieveFormValueForLookupInquiryParameters(parameterName, parameterValuePropertyName);
 407  
                     } else {
 408  0
                             if (LOG.isDebugEnabled()) {
 409  0
                                     LOG.debug("Unable to retrieve lookup/inquiry parameter value for parameter name " + parameterName + " parameter value property " + parameterValuePropertyName);
 410  
                             }
 411  0
                             value = null;
 412  
                     }
 413  
             }
 414  
             
 415  0
             if (value != null && boClass != null && getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(boClass, parameterName)) {
 416  0
                     value = getEncryptionService().encrypt(value) + EncryptionService.ENCRYPTION_POST_PREFIX;
 417  
             }
 418  0
             return value;
 419  
     }
 420  
     
 421  
     /**
 422  
      * Takes care of storing the action form in the User session and forwarding to the lookup action.
 423  
      *
 424  
      * @param mapping
 425  
      * @param form
 426  
      * @param request
 427  
      * @param response
 428  
      * @return
 429  
      * @throws Exception
 430  
      */
 431  
     @SuppressWarnings("unchecked")
 432  
         public ActionForward performLookup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 433  
         // parse out the important strings from our methodToCall parameter
 434  0
         String fullParameter = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 435  0
         validateLookupInquiryFullParameter(request, form, fullParameter);
 436  
         
 437  0
         KualiForm kualiForm = (KualiForm) form;
 438  
         
 439  
         // when we return from the lookup, our next request's method to call is going to be refresh
 440  0
         kualiForm.registerEditableProperty(KNSConstants.DISPATCH_REQUEST_PARAMETER);
 441  
         
 442  
         // parse out the baseLookupUrl if there is one
 443  0
         String baseLookupUrl = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM14_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM14_RIGHT_DEL);
 444  
         
 445  
         // parse out business object class name for lookup
 446  0
         String boClassName = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_BOPARM_LEFT_DEL, KNSConstants.METHOD_TO_CALL_BOPARM_RIGHT_DEL);
 447  0
         if (StringUtils.isBlank(boClassName)) {
 448  0
             throw new RuntimeException("Illegal call to perform lookup, no business object class name specified.");
 449  
         }
 450  0
         Class boClass = null;
 451  
                 try{
 452  0
                         boClass = Class.forName(boClassName);
 453  0
                 } catch(ClassNotFoundException cnfex){
 454  
                         // we must have a valid boClass that can be loaded unless baseLookupUrl is defined
 455  0
                         if (StringUtils.isBlank(baseLookupUrl)) {
 456  0
                                 if ( LOG.isDebugEnabled() ) {
 457  0
                                         LOG.debug( "BO Class " + boClassName + " not found in the current context, checking the RiceApplicationConfigurationService." );
 458  
                                 }
 459  0
                                 baseLookupUrl = KNSServiceLocator.getRiceApplicationConfigurationMediationService().getBaseLookupUrl(boClassName);
 460  0
                                 if ( LOG.isDebugEnabled() ) {
 461  0
                                         LOG.debug( "URL Returned from KSB: " + baseLookupUrl );
 462  
                                 }
 463  0
                                 if ( StringUtils.isBlank(baseLookupUrl)) {
 464  0
                                         throw new IllegalArgumentException("The classname (" + boClassName + ") does not represent a valid class and no base URL could be found on the bus.");
 465  
                                 }
 466  
                         }
 467  0
                 }
 468  
                 
 469  
         // build the parameters for the lookup url
 470  0
         Properties parameters = new Properties();
 471  0
         String conversionFields = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL);
 472  0
         if (StringUtils.isNotBlank(conversionFields)) {
 473  0
             parameters.put(KNSConstants.CONVERSION_FIELDS_PARAMETER, conversionFields);
 474  
             
 475  
             // register each of the destination parameters of the field conversion string as editable
 476  0
             String[] fieldConversions = conversionFields.split(KNSConstants.FIELD_CONVERSIONS_SEPARATOR);
 477  0
             for (int i = 0; i < fieldConversions.length; i++) {
 478  0
                     String destination = fieldConversions[i].split(KNSConstants.FIELD_CONVERSION_PAIR_SEPARATOR)[1];
 479  0
                     kualiForm.registerEditableProperty(destination);
 480  
             }
 481  
         }
 482  
 
 483  
         // pass values from form that should be pre-populated on lookup search
 484  0
         String parameterFields = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM2_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM2_RIGHT_DEL);
 485  0
         if ( LOG.isDebugEnabled() ) {
 486  0
             LOG.debug( "fullParameter: " + fullParameter );
 487  0
             LOG.debug( "parameterFields: " + parameterFields );
 488  
         }
 489  0
         if (StringUtils.isNotBlank(parameterFields)) {
 490  0
             String[] lookupParams = parameterFields.split(KNSConstants.FIELD_CONVERSIONS_SEPARATOR);
 491  0
             if ( LOG.isDebugEnabled() ) {
 492  0
                      LOG.debug( "lookupParams: " + Arrays.toString(lookupParams) ); 
 493  
             }
 494  0
             for (int i = 0; i < lookupParams.length; i++) {
 495  0
                     String[] keyValue = lookupParams[i].split(KNSConstants.FIELD_CONVERSION_PAIR_SEPARATOR); 
 496  0
                 if (keyValue.length != 2) throw new RuntimeException("malformed field conversion pair: " + Arrays.toString(keyValue)); 
 497  
 
 498  0
                 String lookupParameterValue = retrieveLookupParameterValue(boClass, keyValue[1], keyValue[0], form, request);
 499  0
                 if (StringUtils.isNotBlank(lookupParameterValue)) {
 500  0
                         parameters.put(keyValue[1], lookupParameterValue);
 501  
                 }
 502  
 
 503  0
                 if ( LOG.isDebugEnabled() ) {
 504  0
                     LOG.debug( "keyValue[0]: " + keyValue[0] );
 505  0
                     LOG.debug( "keyValue[1]: " + keyValue[1] );
 506  
                 }
 507  
             }
 508  
         }
 509  
 
 510  
         // pass values from form that should be read-Only on lookup search
 511  0
         String readOnlyFields = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM8_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM8_RIGHT_DEL);
 512  0
         if (StringUtils.isNotBlank(readOnlyFields)) {
 513  0
             parameters.put(KNSConstants.LOOKUP_READ_ONLY_FIELDS, readOnlyFields);
 514  
         }
 515  
 
 516  0
         if ( LOG.isDebugEnabled() ) {
 517  0
             LOG.debug( "fullParameter: " + fullParameter );
 518  0
             LOG.debug( "readOnlyFields: " + readOnlyFields );
 519  
         }
 520  
 
 521  
         // grab whether or not the "return value" link should be hidden or not
 522  0
         String hideReturnLink = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM3_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM3_RIGHT_DEL);
 523  0
         if (StringUtils.isNotBlank(hideReturnLink)) {
 524  0
             parameters.put(KNSConstants.HIDE_LOOKUP_RETURN_LINK, hideReturnLink);
 525  
         }
 526  
 
 527  
         // add the optional extra button source and parameters string
 528  0
         String extraButtonSource = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM4_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM4_RIGHT_DEL);
 529  0
         if (StringUtils.isNotBlank(extraButtonSource)) {
 530  0
             parameters.put(KNSConstants.EXTRA_BUTTON_SOURCE, extraButtonSource);
 531  
         }
 532  0
         String extraButtonParams = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM5_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM5_RIGHT_DEL);
 533  0
         if (StringUtils.isNotBlank(extraButtonParams)) {
 534  0
             parameters.put(KNSConstants.EXTRA_BUTTON_PARAMS, extraButtonParams);
 535  
         }
 536  
 
 537  0
         String lookupAction = KNSConstants.LOOKUP_ACTION;
 538  
 
 539  
         // is this a multi-value return?
 540  0
         boolean isMultipleValue = false;
 541  0
         String multipleValues = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM6_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM6_RIGHT_DEL);
 542  0
         if ((new Boolean(multipleValues).booleanValue())) {
 543  0
             parameters.put(KNSConstants.MULTIPLE_VALUE, multipleValues);
 544  0
             lookupAction = KNSConstants.MULTIPLE_VALUE_LOOKUP_ACTION;
 545  0
             isMultipleValue = true;
 546  
         }
 547  
 
 548  
         // the name of the collection being looked up (primarily for multivalue lookups
 549  0
         String lookedUpCollectionName = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM11_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM11_RIGHT_DEL);
 550  0
         if (StringUtils.isNotBlank(lookedUpCollectionName)) {
 551  0
             parameters.put(KNSConstants.LOOKED_UP_COLLECTION_NAME, lookedUpCollectionName);
 552  
         }
 553  
 
 554  
         // grab whether or not the "supress actions" column should be hidden or not
 555  0
         String supressActions = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM7_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM7_RIGHT_DEL);
 556  0
         if (StringUtils.isNotBlank(supressActions)) {
 557  0
             parameters.put(KNSConstants.SUPPRESS_ACTIONS, supressActions);
 558  
         }
 559  
 
 560  
         // grab the references that should be refreshed upon returning from the lookup
 561  0
         String referencesToRefresh = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM10_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM10_RIGHT_DEL);
 562  0
         if (StringUtils.isNotBlank(referencesToRefresh)) {
 563  0
             parameters.put(KNSConstants.REFERENCES_TO_REFRESH, referencesToRefresh);
 564  
         }
 565  
 
 566  
         // anchor, if it exists
 567  0
         if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getAnchor())) {
 568  0
             parameters.put(KNSConstants.LOOKUP_ANCHOR, ((KualiForm) form).getAnchor());
 569  
         }
 570  
 
 571  
         // now add required parameters
 572  0
         parameters.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, "start");
 573  
 
 574  
         // pass value from form that shows if autoSearch is desired for lookup search
 575  0
         String autoSearch = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM9_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM9_RIGHT_DEL);
 576  
 
 577  0
         if (StringUtils.isNotBlank(autoSearch)) {
 578  0
             parameters.put(KNSConstants.LOOKUP_AUTO_SEARCH, autoSearch);
 579  0
             if ("YES".equalsIgnoreCase(autoSearch)){
 580  0
                 parameters.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, "search");
 581  
             }
 582  
         }
 583  
 
 584  0
         parameters.put(KNSConstants.DOC_FORM_KEY, GlobalVariables.getUserSession().addObject(form));
 585  0
         parameters.put(KNSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, boClassName);
 586  
 
 587  0
         parameters.put(KNSConstants.RETURN_LOCATION_PARAMETER, getReturnLocation(request, mapping));
 588  
         
 589  0
             if (form instanceof KualiDocumentFormBase) {
 590  0
                     String docNum = ((KualiDocumentFormBase) form).getDocument().getDocumentNumber();
 591  0
                         if(docNum != null){
 592  0
                                 parameters.put(KNSConstants.DOC_NUM, docNum);
 593  
                         }
 594  0
                 }else if(form instanceof LookupForm){
 595  0
                         String docNum = ((LookupForm) form).getDocNum();
 596  0
                         if(docNum != null){
 597  0
                                 parameters.put(KNSConstants.DOC_NUM, ((LookupForm) form).getDocNum());
 598  
                         }
 599  
             }
 600  
 
 601  0
             if (boClass != null) {
 602  0
                     ModuleService responsibleModuleService = getKualiModuleService().getResponsibleModuleService(boClass);
 603  0
                     if(responsibleModuleService!=null && responsibleModuleService.isExternalizable(boClass)){
 604  0
                             Map<String, String> parameterMap = new HashMap<String, String>();
 605  0
                             Enumeration<Object> e = parameters.keys();
 606  0
                             while (e.hasMoreElements()) {
 607  0
                                     String paramName = (String) e.nextElement();
 608  0
                                     parameterMap.put(paramName, parameters.getProperty(paramName));
 609  0
                             }
 610  0
                             return new ActionForward(responsibleModuleService.getExternalizableBusinessObjectLookupUrl(boClass, parameterMap), true);
 611  
                     }
 612  
             }
 613  
                 
 614  0
             if (StringUtils.isBlank(baseLookupUrl)) {
 615  0
                     baseLookupUrl = getApplicationBaseUrl() + "/kr/" + lookupAction;
 616  
             } else {
 617  0
                     if (isMultipleValue) {
 618  0
                             LookupUtils.transformLookupUrlToMultiple(baseLookupUrl);
 619  
                     }
 620  
             }
 621  0
             String lookupUrl = UrlFactory.parameterizeUrl(baseLookupUrl, parameters);
 622  0
         return new ActionForward(lookupUrl, true);
 623  
     }
 624  
 
 625  
     protected void validateLookupInquiryFullParameter(HttpServletRequest request, ActionForm form, String fullParameter){
 626  0
             PojoFormBase pojoFormBase = (PojoFormBase) form;
 627  0
         if(WebUtils.isFormSessionDocument((PojoFormBase)form)){
 628  0
                 if(!pojoFormBase.isPropertyEditable(fullParameter)) {
 629  0
                         throw new RuntimeException("The methodToCallAttribute is not registered as an editable property.");
 630  
                 }
 631  
         }
 632  0
     }
 633  
     
 634  
     @SuppressWarnings("unchecked")
 635  
         public ActionForward performInquiry(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 636  
         // parse out the important strings from our methodToCall parameter
 637  0
         String fullParameter = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 638  0
         validateLookupInquiryFullParameter(request, form, fullParameter);
 639  
         
 640  
         // when javascript is disabled, the inquiry will appear in the same window as the document.  when we close the inquiry, 
 641  
         // our next request's method to call is going to be refresh
 642  0
         KualiForm kualiForm = (KualiForm) form;
 643  0
         kualiForm.registerEditableProperty(KNSConstants.DISPATCH_REQUEST_PARAMETER);
 644  
         
 645  
         // parse out business object class name for lookup
 646  0
         String boClassName = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_BOPARM_LEFT_DEL, KNSConstants.METHOD_TO_CALL_BOPARM_RIGHT_DEL);
 647  0
         if (StringUtils.isBlank(boClassName)) {
 648  0
             throw new RuntimeException("Illegal call to perform inquiry, no business object class name specified.");
 649  
         }
 650  
 
 651  
         // build the parameters for the inquiry url
 652  0
         Properties parameters = new Properties();
 653  0
         parameters.put(KNSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, boClassName);
 654  
 
 655  0
         parameters.put(KNSConstants.RETURN_LOCATION_PARAMETER, getReturnLocation(request, mapping));
 656  
 
 657  
         // pass values from form that should be pre-populated on inquiry
 658  0
         String parameterFields = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM2_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM2_RIGHT_DEL);
 659  0
         if ( LOG.isDebugEnabled() ) {
 660  0
             LOG.debug( "fullParameter: " + fullParameter );
 661  0
             LOG.debug( "parameterFields: " + parameterFields );
 662  
         }
 663  0
         if (StringUtils.isNotBlank(parameterFields)) {
 664  
             // TODO : create a method for this to be used by both lookup & inquiry ?
 665  0
             String[] inquiryParams = parameterFields.split(KNSConstants.FIELD_CONVERSIONS_SEPARATOR);
 666  0
             if ( LOG.isDebugEnabled() ) {
 667  0
                 LOG.debug( "inquiryParams: " + inquiryParams );
 668  
             }
 669  0
             Class<? extends BusinessObject> boClass = (Class<? extends BusinessObject>) Class.forName(boClassName);
 670  0
             for (int i = 0; i < inquiryParams.length; i++) {
 671  0
                 String[] keyValue = inquiryParams[i].split(KNSConstants.FIELD_CONVERSION_PAIR_SEPARATOR);
 672  
 
 673  0
                 String inquiryParameterValue = retrieveLookupParameterValue(boClass, keyValue[1], keyValue[0], form, request);
 674  0
                 if (inquiryParameterValue == null) {
 675  0
                         parameters.put(keyValue[1], "directInquiryKeyNotSpecified");
 676  
                 }
 677  
                 else {
 678  0
                         parameters.put(keyValue[1], inquiryParameterValue);
 679  
                 }
 680  
 
 681  0
                 if ( LOG.isDebugEnabled() ) {
 682  0
                     LOG.debug( "keyValue[0]: " + keyValue[0] );
 683  0
                     LOG.debug( "keyValue[1]: " + keyValue[1] );
 684  
                 }
 685  
             }
 686  
         }
 687  0
         parameters.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, "start");
 688  0
         parameters.put(KNSConstants.DOC_FORM_KEY, GlobalVariables.getUserSession().addObject(form));
 689  0
         String inquiryUrl = null;
 690  
         try {
 691  0
                 Class.forName(boClassName);
 692  0
                 inquiryUrl = getApplicationBaseUrl() + "/kr/" + KNSConstants.DIRECT_INQUIRY_ACTION;
 693  0
         } catch ( ClassNotFoundException ex ) {
 694  0
                 inquiryUrl = KNSServiceLocator.getRiceApplicationConfigurationMediationService().getBaseInquiryUrl(boClassName);
 695  0
         }
 696  0
         inquiryUrl = UrlFactory.parameterizeUrl(inquiryUrl, parameters);
 697  0
         return new ActionForward(inquiryUrl, true);
 698  
 
 699  
     }
 700  
 
 701  
     /**
 702  
      * This method handles rendering the question component, but without any of the extra error fields
 703  
      *
 704  
      * @param mapping
 705  
      * @param form
 706  
      * @param request
 707  
      * @param response
 708  
      * @param questionId
 709  
      * @param questionText
 710  
      * @param questionType
 711  
      * @param caller
 712  
      * @param context
 713  
      * @return ActionForward
 714  
      * @throws Exception
 715  
      */
 716  
     protected ActionForward performQuestionWithoutInput(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String questionId, String questionText, String questionType, String caller, String context) throws Exception {
 717  0
         return performQuestion(mapping, form, request, response, questionId, questionText, questionType, caller, context, false, "", "", "", "");
 718  
     }
 719  
 
 720  
     /**
 721  
      * Handles rendering a question prompt - without a specified context.
 722  
      *
 723  
      * @param mapping
 724  
      * @param form
 725  
      * @param request
 726  
      * @param response
 727  
      * @param questionId
 728  
      * @param questionText
 729  
      * @param questionType
 730  
      * @param caller
 731  
      * @param context
 732  
      * @return ActionForward
 733  
      * @throws Exception
 734  
      */
 735  
     protected ActionForward performQuestionWithInput(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String questionId, String questionText, String questionType, String caller, String context) throws Exception {
 736  0
         return performQuestion(mapping, form, request, response, questionId, questionText, questionType, caller, context, true, "", "", "", "");
 737  
     }
 738  
 
 739  
     /**
 740  
      * Handles re-rendering a question prompt because of an error on what was submitted.
 741  
      *
 742  
      * @param mapping
 743  
      * @param form
 744  
      * @param request
 745  
      * @param response
 746  
      * @param questionId
 747  
      * @param questionText
 748  
      * @param questionType
 749  
      * @param caller
 750  
      * @param context
 751  
      * @param reason
 752  
      * @param errorKey
 753  
      * @param errorPropertyName
 754  
      * @param errorParameter
 755  
      * @return ActionForward
 756  
      * @throws Exception
 757  
      */
 758  
     protected ActionForward performQuestionWithInputAgainBecauseOfErrors(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String questionId, String questionText, String questionType, String caller, String context, String reason, String errorKey, String errorPropertyName, String errorParameter) throws Exception {
 759  0
         return performQuestion(mapping, form, request, response, questionId, questionText, questionType, caller, context, true, reason, errorKey, errorPropertyName, errorParameter);
 760  
     }
 761  
 
 762  
     /**
 763  
      * Handles rendering a question prompt - with a specified context.
 764  
      *
 765  
      * @param mapping
 766  
      * @param form
 767  
      * @param request
 768  
      * @param response
 769  
      * @param questionId
 770  
      * @param questionText
 771  
      * @param questionType
 772  
      * @param caller
 773  
      * @param context
 774  
      * @param showReasonField
 775  
      * @param reason
 776  
      * @param errorKey
 777  
      * @param errorPropertyName
 778  
      * @param errorParameter
 779  
      * @return ActionForward
 780  
      * @throws Exception
 781  
      */
 782  
     private ActionForward performQuestion(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String questionId, String questionText, String questionType, String caller, String context, boolean showReasonField, String reason, String errorKey, String errorPropertyName, String errorParameter) throws Exception {
 783  0
         Properties parameters = new Properties();
 784  
 
 785  0
         parameters.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, "start");
 786  0
         parameters.put(KNSConstants.DOC_FORM_KEY, GlobalVariables.getUserSession().addObject(form));
 787  0
         parameters.put(KNSConstants.CALLING_METHOD, caller);
 788  0
         parameters.put(KNSConstants.QUESTION_INST_ATTRIBUTE_NAME, questionId);
 789  0
         parameters.put(KNSConstants.QUESTION_IMPL_ATTRIBUTE_NAME, questionType);
 790  0
         parameters.put(KNSConstants.QUESTION_TEXT_ATTRIBUTE_NAME, questionText);
 791  0
         parameters.put(KNSConstants.RETURN_LOCATION_PARAMETER, getReturnLocation(request, mapping));
 792  0
         parameters.put(KNSConstants.QUESTION_CONTEXT, context);
 793  0
         parameters.put(KNSConstants.QUESTION_SHOW_REASON_FIELD, Boolean.toString(showReasonField));
 794  0
         parameters.put(KNSConstants.QUESTION_REASON_ATTRIBUTE_NAME, reason);
 795  0
         parameters.put(KNSConstants.QUESTION_ERROR_KEY, errorKey);
 796  0
         parameters.put(KNSConstants.QUESTION_ERROR_PROPERTY_NAME, errorPropertyName);
 797  0
         parameters.put(KNSConstants.QUESTION_ERROR_PARAMETER, errorParameter);
 798  0
         parameters.put(KNSConstants.QUESTION_ANCHOR, form instanceof KualiForm ? ObjectUtils.toString(((KualiForm) form).getAnchor()) : "");
 799  0
         Object methodToCallAttribute = request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 800  0
         if (methodToCallAttribute != null) {
 801  0
             parameters.put(KNSConstants.METHOD_TO_CALL_PATH, methodToCallAttribute);
 802  0
             ((PojoForm) form).registerEditableProperty(String.valueOf(methodToCallAttribute));
 803  
         }
 804  
         
 805  0
             if (form instanceof KualiDocumentFormBase) {
 806  0
                     String docNum = ((KualiDocumentFormBase) form).getDocument().getDocumentNumber();
 807  0
                     if(docNum != null){
 808  0
                             parameters.put(KNSConstants.DOC_NUM, ((KualiDocumentFormBase) form)
 809  
                                         .getDocument().getDocumentNumber());
 810  
                     }
 811  
                 }
 812  
 
 813  0
         String questionUrl = UrlFactory.parameterizeUrl(getApplicationBaseUrl() + "/kr/" + KNSConstants.QUESTION_ACTION, parameters);
 814  0
         return new ActionForward(questionUrl, true);
 815  
     }
 816  
 
 817  
 
 818  
     /**
 819  
      * Takes care of storing the action form in the User session and forwarding to the workflow workgroup lookup action.
 820  
      *
 821  
      * @param mapping
 822  
      * @param form
 823  
      * @param request
 824  
      * @param response
 825  
      * @return
 826  
      * @throws Exception
 827  
      */
 828  
     public ActionForward performWorkgroupLookup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 829  0
             String returnUrl = null;
 830  0
             if ("/kr".equals(mapping.getModuleConfig().getPrefix())) {
 831  0
                     returnUrl = getApplicationBaseUrl() + mapping.getModuleConfig().getPrefix() + mapping.getPath() + ".do";
 832  
             } else {
 833  0
                     returnUrl = getApplicationBaseUrl() + mapping.getPath() + ".do";
 834  
             }
 835  
 
 836  
 
 837  0
         String fullParameter = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 838  0
         String conversionFields = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL);
 839  
 
 840  0
         String deploymentBaseUrl = KNSServiceLocator.getKualiConfigurationService().getPropertyString(KNSConstants.WORKFLOW_URL_KEY);
 841  0
         String workgroupLookupUrl = deploymentBaseUrl + "/Lookup.do?lookupableImplServiceName=WorkGroupLookupableImplService&methodToCall=start&docFormKey=" + GlobalVariables.getUserSession().addObject(form);
 842  
 
 843  0
         if (conversionFields != null) {
 844  0
             workgroupLookupUrl += "&conversionFields=" + conversionFields;
 845  
         }
 846  0
             if (form instanceof KualiDocumentFormBase) {
 847  0
                         workgroupLookupUrl +="&docNum="+ ((KualiDocumentFormBase) form).getDocument().getDocumentNumber();
 848  
                 }
 849  
             
 850  0
         workgroupLookupUrl += "&returnLocation=" + returnUrl;
 851  
 
 852  0
         return new ActionForward(workgroupLookupUrl, true);
 853  
     }
 854  
 
 855  
     /**
 856  
      * Handles requests that originate via Header Tabs.
 857  
      *
 858  
      * @param mapping
 859  
      * @param form
 860  
      * @param request
 861  
      * @param response
 862  
      * @return
 863  
      * @throws Exception
 864  
      */
 865  
     public ActionForward headerTab(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 866  
         // header tab actions can do two things - 1, call into an action and perform what needs to happen in there and 2, forward to
 867  
         // a new location.
 868  0
         String headerTabDispatch = getHeaderTabDispatch(request);
 869  0
         if (StringUtils.isNotEmpty(headerTabDispatch)) {
 870  0
             ActionForward forward = dispatchMethod(mapping, form, request, response, headerTabDispatch);
 871  0
             if (GlobalVariables.getMessageMap().getNumberOfPropertiesWithErrors() > 0) {
 872  0
                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
 873  
             }
 874  0
             this.doTabOpenOrClose(mapping, form, request, response, false);
 875  0
             if (forward.getRedirect()) {
 876  0
                 return forward;
 877  
             }
 878  
         }
 879  0
         return dispatchMethod(mapping, form, request, response, getHeaderTabNavigateTo(request));
 880  
     }
 881  
 
 882  
     /**
 883  
      * Override this method to provide action-level access controls to the application.
 884  
      *
 885  
      * @param form
 886  
      * @throws AuthorizationException
 887  
      */
 888  
     protected void checkAuthorization( ActionForm form, String methodToCall) throws AuthorizationException 
 889  
     {
 890  0
             String principalId = GlobalVariables.getUserSession().getPrincipalId();
 891  0
             AttributeSet roleQualifier = new AttributeSet(getRoleQualification(form, methodToCall));
 892  0
             AttributeSet permissionDetails = KimCommonUtils.getNamespaceAndActionClass(this.getClass());
 893  
             
 894  0
         if (!KIMServiceLocator.getIdentityManagementService().isAuthorizedByTemplateName(principalId, KNSConstants.KNS_NAMESPACE, 
 895  
                         KimConstants.PermissionTemplateNames.USE_SCREEN, permissionDetails, roleQualifier )) 
 896  
         {
 897  0
             throw new AuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalName(), 
 898  
                             methodToCall,
 899  
                             this.getClass().getSimpleName());
 900  
         }
 901  0
     }
 902  
     
 903  
     /** 
 904  
      * override this method to add data from the form for role qualification in the authorization check
 905  
      */
 906  
     protected Map<String,String> getRoleQualification(ActionForm form, String methodToCall) {
 907  0
             return new HashMap<String,String>();
 908  
     }
 909  
 
 910  
     protected static KualiModuleService getKualiModuleService() {
 911  0
         if ( kualiModuleService == null ) {
 912  0
             kualiModuleService = KNSServiceLocator.getKualiModuleService();
 913  
         }
 914  0
         return kualiModuleService;
 915  
     }
 916  
 
 917  
     /**
 918  
      * Constant defined to match with TextArea.jsp and updateTextArea function in core.js
 919  
      * <p>Value is textAreaFieldName
 920  
      */
 921  
     public static final String TEXT_AREA_FIELD_NAME="textAreaFieldName";
 922  
     /**
 923  
      * Constant defined to match with TextArea.jsp and updateTextArea function in core.js
 924  
      * <p>Value is textAreaFieldLabel
 925  
     */
 926  
     public static final String TEXT_AREA_FIELD_LABEL="textAreaFieldLabel";
 927  
     /**
 928  
      * Constant defined to match with TextArea.jsp and updateTextArea function in core.js
 929  
      * <p>Value is textAreaReadOnly
 930  
     */
 931  
     public static final String TEXT_AREA_READ_ONLY="textAreaReadOnly";
 932  
     /**
 933  
      * Constant defined to match with TextArea.jsp and updateTextArea function in core.js
 934  
      * <p>Value is textAreaFieldAnchor
 935  
     */
 936  
     public static final String TEXT_AREA_FIELD_ANCHOR="textAreaFieldAnchor";
 937  
     /**
 938  
      * Constant defined to match with TextArea.jsp and updateTextArea function in core.js
 939  
      * <p>Value is textAreaFieldAnchor
 940  
     */
 941  
     public static final String TEXT_AREA_MAX_LENGTH="textAreaMaxLength";
 942  
     /**
 943  
      * Constant defined to match with TextArea.jsp and updateTextArea function in core.js
 944  
      * <p>Value is htmlFormAction
 945  
     */
 946  
     public static final String FORM_ACTION="htmlFormAction";
 947  
     /**
 948  
      * Constant defined to match input parameter from URL and from TextArea.jsp.
 949  
      * <p>Value is methodToCall
 950  
     */
 951  
     public static final String METHOD_TO_CALL="methodToCall";
 952  
     /**
 953  
      * Constant defined to match with global forwarding in struts-config.xml
 954  
      * for Text Area Update.
 955  
      * <p>Value is updateTextArea
 956  
     */
 957  
     public static final String FORWARD_TEXT_AREA_UPDATE="updateTextArea";
 958  
     /**
 959  
      * Constant defined to match with method to call in TextArea.jsp.
 960  
      * <p>Value is postTextAreaToParent
 961  
     */
 962  
     public static final String POST_TEXT_AREA_TO_PARENT="postTextAreaToParent";
 963  
     /**
 964  
      * Constant defined to match with local forwarding in struts-config.xml
 965  
      * for the parent of the Updated Text Area.
 966  
      * <p>Value is forwardNext
 967  
     */
 968  
     public static final String FORWARD_NEXT="forwardNext";
 969  
 
 970  
     /**
 971  
      * This method is invoked when Java Script is turned off from the web browser. It
 972  
      * setup the information that the update text area requires for copying current text
 973  
      * in the calling page text area and returning to the calling page. The information
 974  
      * is passed to the JSP through Http Request attributes. All other parameters are
 975  
      * forwarded 
 976  
      *  
 977  
      * @param mapping
 978  
      * @param form
 979  
      * @param request
 980  
      * @param response
 981  
      * @return
 982  
      */
 983  
     public ActionForward updateTextArea(ActionMapping mapping,
 984  
             ActionForm form,
 985  
             HttpServletRequest request,
 986  
             HttpServletResponse response)  {
 987  0
         if (LOG.isTraceEnabled()) {
 988  0
             String lm=String.format("ENTRY %s%n%s", form.getClass().getSimpleName(),
 989  
                     request.getRequestURI());
 990  0
             LOG.trace(lm);
 991  
         }
 992  
                                 
 993  0
         final String[] keyValue = getTextAreaParams(request);
 994  
         
 995  0
         request.setAttribute(TEXT_AREA_FIELD_NAME, keyValue[0]);
 996  0
         request.setAttribute(FORM_ACTION,keyValue[1]);
 997  0
         request.setAttribute(TEXT_AREA_FIELD_LABEL,keyValue[2]);
 998  0
         request.setAttribute(TEXT_AREA_READ_ONLY,keyValue[3]);
 999  0
         request.setAttribute(TEXT_AREA_MAX_LENGTH,keyValue[4]);
 1000  0
         if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getAnchor())) {
 1001  0
             request.setAttribute(TEXT_AREA_FIELD_ANCHOR,((KualiForm) form).getAnchor());
 1002  
         }
 1003  
         
 1004  
         // Set document related parameter
 1005  0
         String docWebScope=(String)request.getAttribute(KNSConstants.DOCUMENT_WEB_SCOPE);
 1006  0
         if (docWebScope != null && docWebScope.trim().length() >= 0) {
 1007  0
             request.setAttribute(KNSConstants.DOCUMENT_WEB_SCOPE, docWebScope);
 1008  
         }
 1009  
 
 1010  0
         request.setAttribute(KNSConstants.DOC_FORM_KEY, GlobalVariables.getUserSession().addObject(form));
 1011  
         
 1012  0
         ActionForward forward=mapping.findForward(FORWARD_TEXT_AREA_UPDATE);
 1013  
 
 1014  0
         if (LOG.isTraceEnabled()) {
 1015  0
             String lm=String.format("EXIT %s", (forward==null)?"null":forward.getPath());
 1016  0
             LOG.trace(lm);
 1017  
         }
 1018  
                         
 1019  0
         return forward;
 1020  
     }
 1021  
     
 1022  
     /**
 1023  
      * This method takes the {@link KNSConstants.METHOD_TO_CALL_ATTRIBUTE} out of the request
 1024  
      * and parses it returning the required fields needed for a text area. The fields returned
 1025  
      * are the following in this order.
 1026  
      * <ol>
 1027  
      * <li>{@link #TEXT_AREA_FIELD_NAME}</li>
 1028  
      * <li>{@link #FORM_ACTION}</li>
 1029  
      * <li>{@link #TEXT_AREA_FIELD_LABEL}</li>
 1030  
      * <li>{@link #TEXT_AREA_READ_ONLY}</li>
 1031  
      * <li>{@link #TEXT_AREA_MAX_LENGTH}</li>
 1032  
      * </ol>
 1033  
      * 
 1034  
      * @param request the request to retrieve the textarea parameters
 1035  
      * @return a string array holding the parsed fields
 1036  
      */
 1037  
     private String[] getTextAreaParams(HttpServletRequest request) {
 1038  
         // parse out the important strings from our methodToCall parameter
 1039  0
         String fullParameter = (String) request.getAttribute(
 1040  
                 KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 1041  
 
 1042  
         // parse textfieldname:htmlformaction
 1043  0
         String parameterFields = StringUtils.substringBetween(fullParameter,
 1044  
                 KNSConstants.METHOD_TO_CALL_PARM2_LEFT_DEL,
 1045  
                 KNSConstants.METHOD_TO_CALL_PARM2_RIGHT_DEL);
 1046  0
         if ( LOG.isDebugEnabled() ) {
 1047  0
             LOG.debug( "fullParameter: " + fullParameter );
 1048  0
             LOG.debug( "parameterFields: " + parameterFields );
 1049  
         }
 1050  0
         String[] keyValue = null;
 1051  0
         if (StringUtils.isNotBlank(parameterFields)) {
 1052  0
             String[] textAreaParams = parameterFields.split(
 1053  
                     KNSConstants.FIELD_CONVERSIONS_SEPARATOR);
 1054  0
             if ( LOG.isDebugEnabled() ) {
 1055  0
                 LOG.debug( "lookupParams: " + textAreaParams );
 1056  
             }
 1057  0
             for (final String textAreaParam : textAreaParams) {
 1058  0
                 keyValue = textAreaParam.split(KNSConstants.FIELD_CONVERSION_PAIR_SEPARATOR);
 1059  
 
 1060  0
                 if ( LOG.isDebugEnabled() ) {
 1061  0
                     LOG.debug( "keyValue[0]: " + keyValue[0] );
 1062  0
                     LOG.debug( "keyValue[1]: " + keyValue[1] );
 1063  0
                     LOG.debug( "keyValue[2]: " + keyValue[2] );
 1064  0
                     LOG.debug( "keyValue[3]: " + keyValue[3] );
 1065  0
                     LOG.debug( "keyValue[4]: " + keyValue[4] );
 1066  
                 }
 1067  
             }
 1068  
         }
 1069  
         
 1070  0
         return keyValue;
 1071  
     }
 1072  
     
 1073  
     /**
 1074  
      * This method is invoked from the TextArea.jsp for posting its value to the parent
 1075  
      * page that called the extended text area page. The invocation is done through
 1076  
      * Struts action. The default forwarding id is RiceContants.MAPPING_BASIC. This
 1077  
      * can be overridden using the parameter key FORWARD_NEXT.
 1078  
      * 
 1079  
      * @param mapping
 1080  
      * @param form
 1081  
      * @param request
 1082  
      * @param response
 1083  
      * @return
 1084  
      */
 1085  
     public ActionForward postTextAreaToParent(ActionMapping mapping,
 1086  
             ActionForm form,
 1087  
             HttpServletRequest request,
 1088  
             HttpServletResponse response) {
 1089  
         
 1090  0
         if (LOG.isTraceEnabled()) {
 1091  0
             String lm=String.format("ENTRY %s%n%s", form.getClass().getSimpleName(),
 1092  
                     request.getRequestURI());
 1093  0
             LOG.trace(lm);
 1094  
         }
 1095  
                         
 1096  0
         String forwardingId=request.getParameter(FORWARD_NEXT);
 1097  0
         if (forwardingId == null) {
 1098  0
             forwardingId=RiceConstants.MAPPING_BASIC;
 1099  
         }
 1100  0
         ActionForward forward=mapping.findForward(forwardingId);
 1101  
              
 1102  0
         if (LOG.isTraceEnabled()) {
 1103  0
             String lm=String.format("EXIT %s", (forward==null)?"null":forward.getPath());
 1104  0
             LOG.trace(lm);
 1105  
         }
 1106  
                         
 1107  0
         return forward;
 1108  
     }
 1109  
     
 1110  
     /**
 1111  
      * Use to add a methodToCall to the a list which will not have authorization checks.
 1112  
      * This assumes that the call will be redirected (as in the case of a lookup) that will perform
 1113  
      * the authorization.
 1114  
      */
 1115  
     protected final void addMethodToCallToUncheckedList( String methodToCall ) {
 1116  0
             methodToCallsToNotCheckAuthorization.add(methodToCall);
 1117  0
     }
 1118  
     
 1119  
     /**
 1120  
      * This method does all special processing on a document that should happen on each HTTP post (ie, save, route, approve, etc).
 1121  
      */
 1122  
     protected void doProcessingAfterPost( KualiForm form, HttpServletRequest request ) {
 1123  
             
 1124  0
     }
 1125  
     
 1126  
     protected BusinessObjectAuthorizationService getBusinessObjectAuthorizationService() {
 1127  0
             if (businessObjectAuthorizationService == null) {
 1128  0
                     businessObjectAuthorizationService = KNSServiceLocator.getBusinessObjectAuthorizationService();
 1129  
             }
 1130  0
             return businessObjectAuthorizationService;
 1131  
     }
 1132  
     
 1133  
     protected EncryptionService getEncryptionService() {
 1134  0
             if (encryptionService == null) {
 1135  0
                     encryptionService = KNSServiceLocator.getEncryptionService();
 1136  
             }
 1137  0
             return encryptionService;
 1138  
     }
 1139  
 
 1140  
         public static String getApplicationBaseUrl() {
 1141  0
                 if ( applicationBaseUrl == null ) {
 1142  0
                         applicationBaseUrl = KNSServiceLocator.getKualiConfigurationService().getPropertyString(KNSConstants.APPLICATION_URL_KEY);
 1143  
                 }
 1144  0
                 return applicationBaseUrl;
 1145  
         }
 1146  
         
 1147  
         /**
 1148  
          * Returns the Base URL for the application server.
 1149  
          * 
 1150  
          * @deprecated Use getApplicationBaseUrl() instead.
 1151  
          */
 1152  
         @Deprecated
 1153  
         protected String getBasePath( HttpServletRequest request ) {
 1154  0
                 return getApplicationBaseUrl();
 1155  
         }
 1156  
 }