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