Coverage Report - org.kuali.rice.kns.util.WebUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
WebUtils
0%
0/356
0%
0/180
3.271
 
 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.util;
 17  
 
 18  
 import org.apache.commons.lang.StringEscapeUtils;
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.apache.log4j.Level;
 21  
 import org.apache.log4j.Logger;
 22  
 import org.apache.struts.Globals;
 23  
 import org.apache.struts.action.ActionForm;
 24  
 import org.apache.struts.action.ActionMapping;
 25  
 import org.apache.struts.action.ActionServletWrapper;
 26  
 import org.apache.struts.upload.CommonsMultipartRequestHandler;
 27  
 import org.apache.struts.upload.FormFile;
 28  
 import org.apache.struts.upload.MultipartRequestHandler;
 29  
 import org.apache.struts.upload.MultipartRequestWrapper;
 30  
 import org.kuali.rice.core.api.config.property.ConfigurationService;
 31  
 import org.kuali.rice.core.api.encryption.EncryptionService;
 32  
 import org.kuali.rice.core.api.services.CoreApiServiceLocator;
 33  
 import org.kuali.rice.core.framework.parameter.ParameterConstants;
 34  
 import org.kuali.rice.core.framework.parameter.ParameterService;
 35  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 36  
 import org.kuali.rice.core.util.RiceKeyConstants;
 37  
 import org.kuali.rice.core.web.format.BooleanFormatter;
 38  
 import org.kuali.rice.kns.UserSession;
 39  
 import org.kuali.rice.kns.bo.BusinessObject;
 40  
 import org.kuali.rice.kns.datadictionary.AttributeDefinition;
 41  
 import org.kuali.rice.kns.datadictionary.AttributeSecurity;
 42  
 import org.kuali.rice.kns.datadictionary.DataDictionary;
 43  
 import org.kuali.rice.kns.datadictionary.DataDictionaryEntryBase;
 44  
 import org.kuali.rice.kns.datadictionary.DocumentEntry;
 45  
 import org.kuali.rice.kns.datadictionary.mask.MaskFormatter;
 46  
 import org.kuali.rice.kns.document.Document;
 47  
 import org.kuali.rice.kns.document.authorization.DocumentAuthorizer;
 48  
 import org.kuali.rice.kns.exception.FileUploadLimitExceededException;
 49  
 import org.kuali.rice.kns.exception.ValidationException;
 50  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 51  
 import org.kuali.rice.kns.service.KNSServiceLocatorWeb;
 52  
 import org.kuali.rice.kns.web.struts.action.KualiMultipartRequestHandler;
 53  
 import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
 54  
 import org.kuali.rice.kns.web.struts.form.KualiForm;
 55  
 import org.kuali.rice.kns.web.struts.form.KualiMaintenanceForm;
 56  
 import org.kuali.rice.kns.web.struts.pojo.PojoFormBase;
 57  
 
 58  
 import javax.servlet.ServletException;
 59  
 import javax.servlet.ServletRequest;
 60  
 import javax.servlet.http.HttpServletRequest;
 61  
 import javax.servlet.http.HttpServletResponse;
 62  
 import javax.servlet.http.HttpSession;
 63  
 import javax.servlet.jsp.PageContext;
 64  
 import java.io.ByteArrayOutputStream;
 65  
 import java.io.IOException;
 66  
 import java.io.InputStream;
 67  
 import java.io.OutputStream;
 68  
 import java.security.GeneralSecurityException;
 69  
 import java.util.Arrays;
 70  
 import java.util.Collection;
 71  
 import java.util.Enumeration;
 72  
 import java.util.HashMap;
 73  
 import java.util.Hashtable;
 74  
 import java.util.Iterator;
 75  
 import java.util.List;
 76  
 import java.util.Map;
 77  
 import java.util.Map.Entry;
 78  
 import java.util.Set;
 79  
 import java.util.regex.Matcher;
 80  
 import java.util.regex.Pattern;
 81  
 
 82  
 /**
 83  
  * General helper methods for handling requests.
 84  
  */
 85  0
 public class WebUtils {
 86  0
         private static final Logger LOG = Logger.getLogger(WebUtils.class);
 87  
 
 88  
         private static final String IMAGE_COORDINATE_CLICKED_X_EXTENSION = ".x";
 89  
         private static final String IMAGE_COORDINATE_CLICKED_Y_EXTENSION = ".y";
 90  
 
 91  
         private static final String APPLICATION_IMAGE_URL_PROPERTY_PREFIX = "application.custom.image.url";
 92  
         private static final String DEFAULT_IMAGE_URL_PROPERTY_NAME = "kr.externalizable.images.url";
 93  
 
 94  
         /**
 95  
          * A request attribute name that indicates that a
 96  
          * {@link FileUploadLimitExceededException} has already been thrown for the
 97  
          * request.
 98  
          */
 99  
         public static final String FILE_UPLOAD_LIMIT_EXCEEDED_EXCEPTION_ALREADY_THROWN = "fileUploadLimitExceededExceptionAlreadyThrown";
 100  
 
 101  
         private static ConfigurationService configurationService;
 102  
 
 103  
         /**
 104  
          * Checks for methodToCall parameter, and picks off the value using set dot
 105  
          * notation. Handles the problem of image submits.
 106  
          * 
 107  
          * @param request
 108  
          * @return methodToCall String
 109  
          */
 110  
         public static String parseMethodToCall(ActionForm form, HttpServletRequest request) {
 111  0
                 String methodToCall = null;
 112  
 
 113  
                 // check if is specified cleanly
 114  0
                 if (StringUtils.isNotBlank(request.getParameter(KNSConstants.DISPATCH_REQUEST_PARAMETER))) {
 115  0
                         if (form instanceof KualiForm
 116  
                                         && !((KualiForm) form).shouldMethodToCallParameterBeUsed(KNSConstants.DISPATCH_REQUEST_PARAMETER,
 117  
                                                         request.getParameter(KNSConstants.DISPATCH_REQUEST_PARAMETER), request)) {
 118  0
                                 throw new RuntimeException("Cannot verify that the methodToCall should be "
 119  
                                                 + request.getParameter(KNSConstants.DISPATCH_REQUEST_PARAMETER));
 120  
                         }
 121  0
                         methodToCall = request.getParameter(KNSConstants.DISPATCH_REQUEST_PARAMETER);
 122  
                         // include .x at the end of the parameter to make it consistent w/
 123  
                         // other parameters
 124  0
                         request.setAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE, KNSConstants.DISPATCH_REQUEST_PARAMETER + "."
 125  
                                         + methodToCall + IMAGE_COORDINATE_CLICKED_X_EXTENSION);
 126  
                 }
 127  
 
 128  
                 /**
 129  
                  * The reason why we are checking for a ".x" at the end of the parameter
 130  
                  * name: It is for the image names that in addition to sending the form
 131  
                  * data, the web browser sends the x,y coordinate of where the user
 132  
                  * clicked on the image. If the image input is not given a name then the
 133  
                  * browser sends the x and y coordinates as the "x" and "y" input
 134  
                  * fields. If the input image does have a name, the x and y coordinates
 135  
                  * are sent using the format name.x and name.y.
 136  
                  */
 137  0
                 if (methodToCall == null) {
 138  
                         // iterate through parameters looking for methodToCall
 139  0
                         for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) {
 140  0
                                 String parameterName = (String) i.nextElement();
 141  
 
 142  
                                 // check if the parameter name is a specifying the methodToCall
 143  0
                                 if (isMethodToCall(parameterName)) {
 144  0
                                         methodToCall = getMethodToCallSettingAttribute(form, request, parameterName);
 145  0
                                         break;
 146  
                                 }
 147  
                                 else {
 148  
                                         // KULRICE-1218: Check if the parameter's values match (not
 149  
                                         // just the name)
 150  0
                                         for (String value : request.getParameterValues(parameterName)) {
 151  
                                                 // adding period to startsWith check - don't want to get
 152  
                                                 // confused with methodToCallFoobar
 153  0
                                                 if (isMethodToCall(value)) {
 154  0
                                                         methodToCall = getMethodToCallSettingAttribute(form, request, value);
 155  
                                                         // why is there not a break outer loop here?
 156  
                                                 }
 157  
                                         }
 158  
                                 }
 159  0
                         }
 160  
                 }
 161  
 
 162  0
                 return methodToCall;
 163  
         }
 164  
 
 165  
         /**
 166  
          * gets the UserSession object from the HttpServletRequest object's
 167  
          * associated session.
 168  
          * 
 169  
          * <p>
 170  
          * In some cases (different threads) the UserSession cannot be retrieved
 171  
          * from GlobalVariables but can still be accessed via the session object
 172  
          * </p>
 173  
          */
 174  
         public static final UserSession getUserSessionFromRequest(HttpServletRequest request) {
 175  0
                 return (UserSession) request.getSession().getAttribute(KNSConstants.USER_SESSION_KEY);
 176  
         }
 177  
 
 178  
         /**
 179  
          * Checks if a string signifies a methodToCall string
 180  
          * 
 181  
          * @param string
 182  
          *            the string to check
 183  
          * @return true if is a methodToCall
 184  
          */
 185  
         private static boolean isMethodToCall(String string) {
 186  
                 // adding period to startsWith check - don't want to get confused with
 187  
                 // methodToCallFoobar
 188  0
                 return string.startsWith(KNSConstants.DISPATCH_REQUEST_PARAMETER + ".");
 189  
         }
 190  
 
 191  
         /**
 192  
          * Parses out the methodToCall command and also sets the request attribute
 193  
          * for the methodToCall.
 194  
          * 
 195  
          * @param form
 196  
          *            the ActionForm
 197  
          * @param request
 198  
          *            the request to set the attribute on
 199  
          * @param string
 200  
          *            the methodToCall string
 201  
          * @return the methodToCall command
 202  
          */
 203  
         private static String getMethodToCallSettingAttribute(ActionForm form, HttpServletRequest request, String string) {
 204  
 
 205  0
                 if (form instanceof ActionForm
 206  
                                 && !((KualiForm) form).shouldMethodToCallParameterBeUsed(string, request.getParameter(string), request)) {
 207  0
                         throw new RuntimeException("Cannot verify that the methodToCall should be " + string);
 208  
                 }
 209  
                 // always adding a coordinate even if not an image
 210  0
                 final String attributeValue = endsWithCoordinates(string) ? string : string
 211  
                                 + IMAGE_COORDINATE_CLICKED_X_EXTENSION;
 212  0
                 final String methodToCall = StringUtils.substringBetween(attributeValue,
 213  
                                 KNSConstants.DISPATCH_REQUEST_PARAMETER + ".", ".");
 214  0
                 request.setAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE, attributeValue);
 215  0
                 return methodToCall;
 216  
         }
 217  
 
 218  
         /**
 219  
          * Iterates through and logs (at the given level) all attributes and
 220  
          * parameters of the given request onto the given Logger
 221  
          * 
 222  
          * @param request
 223  
          * @param logger
 224  
          */
 225  
         public static void logRequestContents(Logger logger, Level level, HttpServletRequest request) {
 226  0
                 if (logger.isEnabledFor(level)) {
 227  0
                         logger.log(level, "--------------------");
 228  0
                         logger.log(level, "HttpRequest attributes:");
 229  0
                         for (Enumeration e = request.getAttributeNames(); e.hasMoreElements();) {
 230  0
                                 String attrName = (String) e.nextElement();
 231  0
                                 Object attrValue = request.getAttribute(attrName);
 232  
 
 233  0
                                 if (attrValue.getClass().isArray()) {
 234  0
                                         logCollection(logger, level, attrName, Arrays.asList((Object[]) attrValue));
 235  
                                 }
 236  0
                                 else if (attrValue instanceof Collection) {
 237  0
                                         logCollection(logger, level, attrName, (Collection) attrValue);
 238  
                                 }
 239  0
                                 else if (attrValue instanceof Map) {
 240  0
                                         logMap(logger, level, attrName, (Map) attrValue);
 241  
                                 }
 242  
                                 else {
 243  0
                                         logObject(logger, level, attrName, attrValue);
 244  
                                 }
 245  0
                         }
 246  
 
 247  0
                         logger.log(level, "--------------------");
 248  0
                         logger.log(level, "HttpRequest parameters:");
 249  0
                         for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) {
 250  0
                                 String paramName = (String) i.nextElement();
 251  0
                                 String[] paramValues = (String[]) request.getParameterValues(paramName);
 252  
 
 253  0
                                 logArray(logger, level, paramName, paramValues);
 254  0
                         }
 255  
 
 256  0
                         logger.log(level, "--------------------");
 257  
                 }
 258  0
         }
 259  
 
 260  
         private static void logArray(Logger logger, Level level, String arrayName, Object[] array) {
 261  0
                 StringBuffer value = new StringBuffer("[");
 262  0
                 for (int i = 0; i < array.length; ++i) {
 263  0
                         if (i > 0) {
 264  0
                                 value.append(",");
 265  
                         }
 266  0
                         value.append(array[i]);
 267  
                 }
 268  0
                 value.append("]");
 269  
 
 270  0
                 logThing(logger, level, arrayName, value);
 271  0
         }
 272  
 
 273  
         private static void logCollection(Logger logger, Level level, String collectionName, Collection c) {
 274  0
                 StringBuffer value = new StringBuffer("{");
 275  0
                 for (Iterator i = c.iterator(); i.hasNext();) {
 276  0
                         value.append(i.next());
 277  0
                         if (i.hasNext()) {
 278  0
                                 value.append(",");
 279  
                         }
 280  
                 }
 281  0
                 value.append("}");
 282  
 
 283  0
                 logThing(logger, level, collectionName, value);
 284  0
         }
 285  
 
 286  
         private static void logMap(Logger logger, Level level, String mapName, Map m) {
 287  0
                 StringBuffer value = new StringBuffer("{");
 288  0
                 for (Iterator i = m.entrySet().iterator(); i.hasNext();) {
 289  0
                         Map.Entry e = (Map.Entry) i.next();
 290  0
                         value.append("('" + e.getKey() + "','" + e.getValue() + "')");
 291  0
                 }
 292  0
                 value.append("}");
 293  
 
 294  0
                 logThing(logger, level, mapName, value);
 295  0
         }
 296  
 
 297  
         private static void logObject(Logger logger, Level level, String objectName, Object o) {
 298  0
                 logThing(logger, level, objectName, "'" + o + "'");
 299  0
         }
 300  
 
 301  
         private static void logThing(Logger logger, Level level, String thingName, Object thing) {
 302  0
                 logger.log(level, "    '" + thingName + "' => " + thing);
 303  0
         }
 304  
 
 305  
         /**
 306  
          * A file that is not of type text/plain or text/html can be output through
 307  
          * the response using this method.
 308  
          * 
 309  
          * @param response
 310  
          * @param contentType
 311  
          * @param outStream
 312  
          * @param fileName
 313  
          */
 314  
         public static void saveMimeOutputStreamAsFile(HttpServletResponse response, String contentType,
 315  
                         ByteArrayOutputStream byteArrayOutputStream, String fileName) throws IOException {
 316  
 
 317  
                 // set response
 318  0
                 response.setContentType(contentType);
 319  0
                 response.setHeader("Content-disposition", "attachment; filename=" + fileName);
 320  0
                 response.setHeader("Expires", "0");
 321  0
                 response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
 322  0
                 response.setHeader("Pragma", "public");
 323  0
                 response.setContentLength(byteArrayOutputStream.size());
 324  
 
 325  
                 // write to output
 326  0
                 OutputStream outputStream = response.getOutputStream();
 327  0
                 byteArrayOutputStream.writeTo(response.getOutputStream());
 328  0
                 outputStream.flush();
 329  0
                 outputStream.close();
 330  0
         }
 331  
 
 332  
         /**
 333  
          * A file that is not of type text/plain or text/html can be output through
 334  
          * the response using this method.
 335  
          * 
 336  
          * @param response
 337  
          * @param contentType
 338  
          * @param outStream
 339  
          * @param fileName
 340  
          */
 341  
         public static void saveMimeInputStreamAsFile(HttpServletResponse response, String contentType,
 342  
                         InputStream inStream, String fileName, int fileSize) throws IOException {
 343  
 
 344  
                 // set response
 345  0
                 response.setContentType(contentType);
 346  0
                 response.setHeader("Content-disposition", "attachment; filename=" + fileName);
 347  0
                 response.setHeader("Expires", "0");
 348  0
                 response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
 349  0
                 response.setHeader("Pragma", "public");
 350  0
                 response.setContentLength(fileSize);
 351  
 
 352  
                 // write to output
 353  0
                 OutputStream out = response.getOutputStream();
 354  0
                 while (inStream.available() > 0) {
 355  0
                         out.write(inStream.read());
 356  
                 }
 357  0
                 out.flush();
 358  0
         }
 359  
 
 360  
         /**
 361  
          * JSTL function to return the tab state of the tab from the form.
 362  
          * 
 363  
          * @param form
 364  
          * @param tabKey
 365  
          * @return
 366  
          */
 367  
         public static String getTabState(KualiForm form, String tabKey) {
 368  0
                 return form.getTabState(tabKey);
 369  
         }
 370  
 
 371  
         public static void incrementTabIndex(KualiForm form, String tabKey) {
 372  0
                 form.incrementTabIndex();
 373  0
         }
 374  
 
 375  
         /**
 376  
          * Generates a String from the title that can be used as a Map key.
 377  
          * 
 378  
          * @param tabTitle
 379  
          * @return
 380  
          */
 381  
         public static String generateTabKey(String tabTitle) {
 382  0
                 String key = "";
 383  0
                 if (!StringUtils.isBlank(tabTitle)) {
 384  0
                         key = tabTitle.replaceAll("\\W", "");
 385  
                         // if (key.length() > 25) {
 386  
                         // key = key.substring(0, 24);
 387  
                         // }
 388  
                 }
 389  
 
 390  0
                 return key;
 391  
         }
 392  
 
 393  
         public static void getMultipartParameters(HttpServletRequest request, ActionServletWrapper servletWrapper,
 394  
                         ActionForm form, ActionMapping mapping) {
 395  0
                 Map params = new HashMap();
 396  
 
 397  
                 // Get the ActionServletWrapper from the form bean
 398  
                 // ActionServletWrapper servletWrapper = getServletWrapper();
 399  
 
 400  
                 try {
 401  0
                         CommonsMultipartRequestHandler multipartHandler = new CommonsMultipartRequestHandler();
 402  0
                         if (multipartHandler != null) {
 403  
                                 // Set servlet and mapping info
 404  0
                                 if (servletWrapper != null) {
 405  
                                         // from pojoformbase
 406  
                                         // servlet only affects tempdir on local disk
 407  0
                                         servletWrapper.setServletFor(multipartHandler);
 408  
                                 }
 409  0
                                 multipartHandler.setMapping((ActionMapping) request.getAttribute(Globals.MAPPING_KEY));
 410  
                                 // Initialize multipart request class handler
 411  0
                                 multipartHandler.handleRequest(request);
 412  
 
 413  0
                                 Collection<FormFile> files = multipartHandler.getFileElements().values();
 414  0
                                 Enumeration keys = multipartHandler.getFileElements().keys();
 415  
 
 416  0
                                 while (keys.hasMoreElements()) {
 417  0
                                         Object key = keys.nextElement();
 418  0
                                         FormFile file = (FormFile) multipartHandler.getFileElements().get(key);
 419  0
                                         long maxSize = WebUtils.getMaxUploadSize(form);
 420  0
                                         if (LOG.isDebugEnabled()) {
 421  0
                                                 LOG.debug(file.getFileSize());
 422  
                                         }
 423  0
                                         if (maxSize > 0 && Long.parseLong(file.getFileSize() + "") > maxSize) {
 424  
 
 425  0
                                                 GlobalVariables.getMessageMap().putError(key.toString(),
 426  
                                                                 RiceKeyConstants.ERROR_UPLOADFILE_SIZE,
 427  
                                                                 new String[] { file.getFileName(), Long.toString(maxSize) });
 428  
 
 429  
                                         }
 430  0
                                 }
 431  
 
 432  
                                 // get file elements for kualirequestprocessor
 433  0
                                 if (servletWrapper == null) {
 434  0
                                         request.setAttribute(KNSConstants.UPLOADED_FILE_REQUEST_ATTRIBUTE_KEY,
 435  
                                                         getFileParametersForMultipartRequest(request, multipartHandler));
 436  
                                 }
 437  
                         }
 438  
                 }
 439  0
                 catch (ServletException e) {
 440  0
                         throw new ValidationException("unable to handle multipart request " + e.getMessage(), e);
 441  0
                 }
 442  0
         }
 443  
 
 444  
         public static long getMaxUploadSize(ActionForm form) {
 445  0
                 long max = 0L;
 446  0
                 KualiMultipartRequestHandler multipartHandler = new KualiMultipartRequestHandler();
 447  0
                 if (form instanceof PojoFormBase) {
 448  0
                         max = multipartHandler.calculateMaxUploadSizeToMaxOfList(((PojoFormBase) form).getMaxUploadSizes());
 449  
                 }
 450  0
                 if (LOG.isDebugEnabled()) {
 451  0
                         LOG.debug("Max File Upload Size: " + max);
 452  
                 }
 453  0
                 return max;
 454  
         }
 455  
 
 456  
         private static Map getFileParametersForMultipartRequest(HttpServletRequest request,
 457  
                         MultipartRequestHandler multipartHandler) {
 458  0
                 Map parameters = new HashMap();
 459  0
                 Hashtable elements = multipartHandler.getFileElements();
 460  0
                 Enumeration e = elements.keys();
 461  0
                 while (e.hasMoreElements()) {
 462  0
                         String key = (String) e.nextElement();
 463  0
                         parameters.put(key, elements.get(key));
 464  0
                 }
 465  
 
 466  0
                 if (request instanceof MultipartRequestWrapper) {
 467  0
                         request = (HttpServletRequest) ((MultipartRequestWrapper) request).getRequest();
 468  0
                         e = request.getParameterNames();
 469  0
                         while (e.hasMoreElements()) {
 470  0
                                 String key = (String) e.nextElement();
 471  0
                                 parameters.put(key, request.getParameterValues(key));
 472  0
                         }
 473  
                 }
 474  
                 else {
 475  0
                         LOG.debug("Gathering multipart parameters for unwrapped request");
 476  
                 }
 477  0
                 return parameters;
 478  
         }
 479  
 
 480  
         // end multipart
 481  
 
 482  
         public static void registerEditableProperty(PojoFormBase form, String editablePropertyName) {
 483  0
                 form.registerEditableProperty(editablePropertyName);
 484  0
         }
 485  
 
 486  
         public static boolean isDocumentSession(Document document, PojoFormBase docForm) {
 487  0
                 boolean sessionDoc = document instanceof org.kuali.rice.kns.document.SessionDocument;
 488  0
                 boolean dataDictionarySessionDoc = false;
 489  0
                 if (!sessionDoc) {
 490  0
                         DocumentEntry documentEntry = null;
 491  0
                         DataDictionary dataDictionary = KNSServiceLocatorWeb.getDataDictionaryService().getDataDictionary();
 492  0
                         if (docForm instanceof KualiMaintenanceForm) {
 493  0
                                 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) docForm;
 494  0
                                 if (dataDictionary != null) {
 495  0
                                         if (maintenanceForm.getDocTypeName() != null) {
 496  0
                                                 documentEntry = dataDictionary.getDocumentEntry(maintenanceForm.getDocTypeName());
 497  0
                                                 dataDictionarySessionDoc = documentEntry.isSessionDocument();
 498  
                                         }
 499  
                                 }
 500  0
                         }
 501  
                         else {
 502  0
                                 if (document != null && dataDictionary != null) {
 503  0
                                         documentEntry = dataDictionary.getDocumentEntry(document.getClass().getName());
 504  0
                                         dataDictionarySessionDoc = documentEntry.isSessionDocument();
 505  
                                 }
 506  
                         }
 507  
                 }
 508  0
                 return sessionDoc || dataDictionarySessionDoc;
 509  
         }
 510  
 
 511  
         public static boolean isFormSessionDocument(PojoFormBase form) {
 512  0
                 Document document = null;
 513  0
                 if (KualiDocumentFormBase.class.isAssignableFrom(form.getClass())) {
 514  0
                         KualiDocumentFormBase docForm = (KualiDocumentFormBase) form;
 515  0
                         document = docForm.getDocument();
 516  
                 }
 517  0
                 return isDocumentSession(document, form);
 518  
         }
 519  
 
 520  0
         public static String KEY_KUALI_FORM_IN_SESSION = "KualiForm";
 521  
 
 522  
         public static ActionForm getKualiForm(PageContext pageContext) {
 523  0
                 return getKualiForm((HttpServletRequest) pageContext.getRequest());
 524  
         }
 525  
 
 526  
         public static ActionForm getKualiForm(HttpServletRequest request) {
 527  0
                 if (request.getAttribute(KEY_KUALI_FORM_IN_SESSION) != null) {
 528  0
                         return (ActionForm) request.getAttribute(KEY_KUALI_FORM_IN_SESSION);
 529  
                 }
 530  
                 else {
 531  0
                         final HttpSession session = request.getSession(false);
 532  0
                         return session != null ? (ActionForm) session.getAttribute(KEY_KUALI_FORM_IN_SESSION) : null;
 533  
                 }
 534  
         }
 535  
 
 536  
         public static boolean isPropertyEditable(Set<String> editableProperties, String propertyName) {
 537  0
                 if (LOG.isDebugEnabled()) {
 538  0
                         LOG.debug("isPropertyEditable(" + propertyName + ")");
 539  
                 }
 540  
 
 541  0
                 boolean returnVal = editableProperties == null
 542  
                                 || editableProperties.contains(propertyName)
 543  
                                 || (getIndexOfCoordinateExtension(propertyName) == -1 ? false : editableProperties
 544  
                                                 .contains(propertyName.substring(0, getIndexOfCoordinateExtension(propertyName))));
 545  0
                 if (!returnVal) {
 546  0
                         if (LOG.isDebugEnabled()) {
 547  0
                                 LOG.debug("isPropertyEditable(" + propertyName + ") == false / editableProperties: "
 548  
                                                 + editableProperties);
 549  
                         }
 550  
                 }
 551  0
                 return returnVal;
 552  
         }
 553  
 
 554  
         public static boolean endsWithCoordinates(String parameter) {
 555  0
                 return parameter.endsWith(WebUtils.IMAGE_COORDINATE_CLICKED_X_EXTENSION)
 556  
                                 || parameter.endsWith(WebUtils.IMAGE_COORDINATE_CLICKED_Y_EXTENSION);
 557  
         }
 558  
 
 559  
         public static int getIndexOfCoordinateExtension(String parameter) {
 560  0
                 int indexOfCoordinateExtension = parameter.lastIndexOf(WebUtils.IMAGE_COORDINATE_CLICKED_X_EXTENSION);
 561  0
                 if (indexOfCoordinateExtension == -1)
 562  0
                         indexOfCoordinateExtension = parameter.lastIndexOf(WebUtils.IMAGE_COORDINATE_CLICKED_Y_EXTENSION);
 563  0
                 return indexOfCoordinateExtension;
 564  
         }
 565  
 
 566  
     public static boolean isInquiryHiddenField(String className, String fieldName, Object formObject, String propertyName) {
 567  0
             boolean isHidden = false;
 568  0
             String hiddenInquiryFields = getKualiConfigurationService().getPropertyString(className+".hidden");
 569  0
             if (StringUtils.isEmpty(hiddenInquiryFields)) {
 570  0
                     return isHidden;
 571  
             }
 572  0
             List hiddenFields = Arrays.asList(hiddenInquiryFields.replaceAll(" ", "").split(","));
 573  0
             if (hiddenFields.contains(fieldName.trim())) {
 574  0
                     isHidden = true;
 575  
             }
 576  0
             return isHidden;
 577  
     }
 578  
 
 579  
     public static boolean isHiddenKimObjectType(String type, String configParameter) {
 580  0
             boolean hideType = false;
 581  0
             String hiddenTypes = getKualiConfigurationService().getPropertyString(configParameter);
 582  0
             if (StringUtils.isEmpty(hiddenTypes)) {
 583  0
                     return hideType;
 584  
             }
 585  0
             List hiddenTypeValues = Arrays.asList(hiddenTypes.replaceAll(" ", "").split(","));
 586  0
             if (hiddenTypeValues.contains(type.trim())) {
 587  0
                     hideType = true;
 588  
             }
 589  0
             return hideType;
 590  
     }
 591  
 
 592  
         public static String getFullyMaskedValue(String className, String fieldName, Object formObject, String propertyName) {
 593  0
                 String displayMaskValue = null;
 594  0
                 Object propertyValue = ObjectUtils.getPropertyValue(formObject, propertyName);
 595  
 
 596  0
                 DataDictionaryEntryBase entry = (DataDictionaryEntryBase) KNSServiceLocatorWeb.getDataDictionaryService()
 597  
                                 .getDataDictionary().getDictionaryObjectEntry(className);
 598  0
                 AttributeDefinition a = entry.getAttributeDefinition(fieldName);
 599  
 
 600  0
                 AttributeSecurity attributeSecurity = a.getAttributeSecurity();
 601  0
                 if (attributeSecurity != null && attributeSecurity.isMask()) {
 602  0
                         MaskFormatter maskFormatter = attributeSecurity.getMaskFormatter();
 603  0
                         displayMaskValue = maskFormatter.maskValue(propertyValue);
 604  
 
 605  
                 }
 606  0
                 return displayMaskValue;
 607  
         }
 608  
 
 609  
         public static String getPartiallyMaskedValue(String className, String fieldName, Object formObject,
 610  
                         String propertyName) {
 611  0
                 String displayMaskValue = null;
 612  0
                 Object propertyValue = ObjectUtils.getPropertyValue(formObject, propertyName);
 613  
 
 614  0
                 DataDictionaryEntryBase entry = (DataDictionaryEntryBase) KNSServiceLocatorWeb.getDataDictionaryService()
 615  
                                 .getDataDictionary().getDictionaryObjectEntry(className);
 616  0
                 AttributeDefinition a = entry.getAttributeDefinition(fieldName);
 617  
 
 618  0
                 AttributeSecurity attributeSecurity = a.getAttributeSecurity();
 619  0
                 if (attributeSecurity != null && attributeSecurity.isPartialMask()) {
 620  0
                         MaskFormatter partialMaskFormatter = attributeSecurity.getPartialMaskFormatter();
 621  0
                         displayMaskValue = partialMaskFormatter.maskValue(propertyValue);
 622  
 
 623  
                 }
 624  0
                 return displayMaskValue;
 625  
         }
 626  
 
 627  
         public static boolean canFullyUnmaskField(String businessObjectClassName, String fieldName, KualiForm form) {
 628  0
                 Class businessObjClass = null;
 629  
                 try {
 630  0
                         businessObjClass = Class.forName(businessObjectClassName);
 631  
                 }
 632  0
                 catch (Exception e) {
 633  0
                         throw new RuntimeException("Unable to resolve class name: " + businessObjectClassName);
 634  0
                 }
 635  0
                 if (form instanceof KualiDocumentFormBase) {
 636  0
                         return KNSServiceLocatorWeb.getBusinessObjectAuthorizationService().canFullyUnmaskField(
 637  
                                         GlobalVariables.getUserSession().getPerson(), businessObjClass, fieldName,
 638  
                                         ((KualiDocumentFormBase) form).getDocument());
 639  
                 }
 640  
                 else {
 641  0
                         return KNSServiceLocatorWeb.getBusinessObjectAuthorizationService().canFullyUnmaskField(
 642  
                                         GlobalVariables.getUserSession().getPerson(), businessObjClass, fieldName, null);
 643  
                 }
 644  
         }
 645  
 
 646  
         public static boolean canPartiallyUnmaskField(String businessObjectClassName, String fieldName, KualiForm form) {
 647  0
                 Class businessObjClass = null;
 648  
                 try {
 649  0
                         businessObjClass = Class.forName(businessObjectClassName);
 650  
                 }
 651  0
                 catch (Exception e) {
 652  0
                         throw new RuntimeException("Unable to resolve class name: " + businessObjectClassName);
 653  0
                 }
 654  0
                 if (form instanceof KualiDocumentFormBase) {
 655  0
                         return KNSServiceLocatorWeb.getBusinessObjectAuthorizationService().canPartiallyUnmaskField(
 656  
                                         GlobalVariables.getUserSession().getPerson(), businessObjClass, fieldName,
 657  
                                         ((KualiDocumentFormBase) form).getDocument());
 658  
                 }
 659  
                 else {
 660  0
                         return KNSServiceLocatorWeb.getBusinessObjectAuthorizationService().canPartiallyUnmaskField(
 661  
                                         GlobalVariables.getUserSession().getPerson(), businessObjClass, fieldName, null);
 662  
                 }
 663  
         }
 664  
 
 665  
         public static boolean canAddNoteAttachment(Document document) {
 666  0
                 boolean canViewNoteAttachment = false;
 667  0
                 DocumentAuthorizer documentAuthorizer = KNSServiceLocatorWeb.getDocumentHelperService().getDocumentAuthorizer(
 668  
                                 document);
 669  0
                 canViewNoteAttachment = documentAuthorizer.canAddNoteAttachment(document, null, GlobalVariables
 670  
                                 .getUserSession().getPerson());
 671  0
                 return canViewNoteAttachment;
 672  
         }
 673  
 
 674  
         public static boolean canViewNoteAttachment(Document document, String attachmentTypeCode) {
 675  0
                 boolean canViewNoteAttachment = false;
 676  0
                 DocumentAuthorizer documentAuthorizer = KNSServiceLocatorWeb.getDocumentHelperService().getDocumentAuthorizer(
 677  
                                 document);
 678  0
                 canViewNoteAttachment = documentAuthorizer.canViewNoteAttachment(document, attachmentTypeCode, GlobalVariables
 679  
                                 .getUserSession().getPerson());
 680  0
                 return canViewNoteAttachment;
 681  
         }
 682  
 
 683  
         public static boolean canDeleteNoteAttachment(Document document, String attachmentTypeCode,
 684  
                         String authorUniversalIdentifier) {
 685  0
                 boolean canDeleteNoteAttachment = false;
 686  0
                 DocumentAuthorizer documentAuthorizer = KNSServiceLocatorWeb.getDocumentHelperService().getDocumentAuthorizer(
 687  
                                 document);
 688  0
                 canDeleteNoteAttachment = documentAuthorizer.canDeleteNoteAttachment(document, attachmentTypeCode, "false",
 689  
                                 GlobalVariables.getUserSession().getPerson());
 690  0
                 if (canDeleteNoteAttachment) {
 691  0
                         return canDeleteNoteAttachment;
 692  
                 }
 693  
                 else {
 694  0
                         canDeleteNoteAttachment = documentAuthorizer.canDeleteNoteAttachment(document, attachmentTypeCode, "true",
 695  
                                         GlobalVariables.getUserSession().getPerson());
 696  0
                         if (canDeleteNoteAttachment
 697  
                                         && !authorUniversalIdentifier.equals(GlobalVariables.getUserSession().getPerson().getPrincipalId())) {
 698  0
                                 canDeleteNoteAttachment = false;
 699  
                         }
 700  
                 }
 701  0
                 return canDeleteNoteAttachment;
 702  
         }
 703  
 
 704  
         public static void reuseErrorMapFromPreviousRequest(KualiDocumentFormBase kualiDocumentFormBase) {
 705  0
                 if (kualiDocumentFormBase.getMessageMapFromPreviousRequest() == null) {
 706  0
                         LOG.error("Error map from previous request is null!");
 707  0
                         return;
 708  
                 }
 709  0
                 MessageMap errorMapFromGlobalVariables = GlobalVariables.getMessageMap();
 710  0
                 if (kualiDocumentFormBase.getMessageMapFromPreviousRequest() == errorMapFromGlobalVariables) {
 711  
                         // if we've switched them already, then return early and do nothing
 712  0
                         return;
 713  
                 }
 714  0
                 if (!errorMapFromGlobalVariables.hasNoErrors()) {
 715  0
                         throw new RuntimeException("Cannot replace error map because it is not empty");
 716  
                 }
 717  0
                 GlobalVariables.setMessageMap(kualiDocumentFormBase.getMessageMapFromPreviousRequest());
 718  0
                 GlobalVariables.getMessageMap().clearErrorPath();
 719  0
         }
 720  
 
 721  
         /**
 722  
          * Excapes out HTML to prevent XSS attacks, and replaces the following
 723  
          * strings to allow for a limited set of HTML tags
 724  
          * 
 725  
          * <li>[X] and [/X], where X represents any 1 or 2 letter string may be used
 726  
          * to specify the equivalent tag in HTML (i.e. &lt;X&gt; and &lt;/X&gt;) <li>
 727  
          * [font COLOR], where COLOR represents any valid html color (i.e. color
 728  
          * name or hexcode preceeded by #) will be filtered into &lt;font
 729  
          * color="COLOR"/&gt; <li>[/font] will be filtered into &lt;/font&gt; <li>
 730  
          * [table CLASS], where CLASS gives the style class to use, will be filter
 731  
          * into &lt;table class="CLASS"/&gt; <li>[/table] will be filtered into
 732  
          * &lt;/table&gt; <li>[td CLASS], where CLASS gives the style class to use,
 733  
          * will be filter into &lt;td class="CLASS"/&gt;
 734  
          * 
 735  
          * @param inputString
 736  
          * @return
 737  
          */
 738  
         public static String filterHtmlAndReplaceRiceMarkup(String inputString) {
 739  0
                 String outputString = StringEscapeUtils.escapeHtml(inputString);
 740  
                 // string has been escaped of all <, >, and & (and other characters)
 741  
 
 742  0
                 Map<String, String> findAndReplacePatterns = new HashMap<String, String>();
 743  
 
 744  
                 // now replace our rice custom markup into html
 745  
 
 746  
                 // DON'T ALLOW THE SCRIPT TAG OR ARBITRARY IMAGES/URLS/ETC. THROUGH
 747  
 
 748  
                 // filter any one character tags
 749  0
                 findAndReplacePatterns.put("\\[([A-Za-z])\\]", "<$1>");
 750  0
                 findAndReplacePatterns.put("\\[/([A-Za-z])\\]", "</$1>");
 751  
                 // filter any two character tags
 752  0
                 findAndReplacePatterns.put("\\[([A-Za-z]{2})\\]", "<$1>");
 753  0
                 findAndReplacePatterns.put("\\[/([A-Za-z]{2})\\]", "</$1>");
 754  
                 // filter the font tag
 755  0
                 findAndReplacePatterns.put("\\[font (#[0-9A-Fa-f]{1,6}|[A-Za-z]+)\\]", "<font color=\"$1\">");
 756  0
                 findAndReplacePatterns.put("\\[/font\\]", "</font>");
 757  
                 // filter the table tag
 758  0
                 findAndReplacePatterns.put("\\[table\\]", "<table>");
 759  0
                 findAndReplacePatterns.put("\\[table ([A-Za-z]+)\\]", "<table class=\"$1\">");
 760  0
                 findAndReplacePatterns.put("\\[/table\\]", "</table>");
 761  
                 // fiter td with class
 762  0
                 findAndReplacePatterns.put("\\[td ([A-Za-z]+)\\]", "<td class=\"$1\">");
 763  
 
 764  0
                 for (String findPattern : findAndReplacePatterns.keySet()) {
 765  0
                         Pattern p = Pattern.compile(findPattern);
 766  0
                         Matcher m = p.matcher(outputString);
 767  0
                         if (m.find()) {
 768  0
                                 String replacePattern = findAndReplacePatterns.get(findPattern);
 769  0
                                 outputString = m.replaceAll(replacePattern);
 770  
                         }
 771  0
                 }
 772  
 
 773  0
                 return outputString;
 774  
         }
 775  
 
 776  
         public static boolean containsSensitiveDataPatternMatch(String fieldValue) {
 777  0
                 if (StringUtils.isBlank(fieldValue)) {
 778  0
                         return false;
 779  
                 }
 780  0
                 ParameterService parameterService = CoreFrameworkServiceLocator.getParameterService();
 781  0
                 Collection<String> sensitiveDataPatterns = parameterService.getParameterValuesAsString(KNSConstants.KNS_NAMESPACE,
 782  
                                 ParameterConstants.ALL_COMPONENT, KNSConstants.SystemGroupParameterNames.SENSITIVE_DATA_PATTERNS);
 783  0
                 for (String pattern : sensitiveDataPatterns) {
 784  0
                         if (Pattern.compile(pattern).matcher(fieldValue).find()) {
 785  0
                                 return true;
 786  
                         }
 787  
                 }
 788  0
                 return false;
 789  
         }
 790  
 
 791  
         /**
 792  
          * Determines and returns the URL for question button images; looks first
 793  
          * for a property "application.custom.image.url", and if that is missing,
 794  
          * uses the image url returned by getDefaultButtonImageUrl()
 795  
          * 
 796  
          * @param imageName
 797  
          *            the name of the image to find a button for
 798  
          * @return the URL where question button images are located
 799  
          */
 800  
         public static String getButtonImageUrl(String imageName) {
 801  0
                 String buttonImageUrl = getKualiConfigurationService().getPropertyString(
 802  
                                 WebUtils.APPLICATION_IMAGE_URL_PROPERTY_PREFIX + "." + imageName);
 803  0
                 if (StringUtils.isBlank(buttonImageUrl)) {
 804  0
                         buttonImageUrl = getDefaultButtonImageUrl(imageName);
 805  
                 }
 806  0
                 return buttonImageUrl;
 807  
         }
 808  
 
 809  
         /**
 810  
          * Generates a default button image URL, in the form of:
 811  
          * ${kr.externalizable.images.url}buttonsmall_${imageName}.gif
 812  
          * 
 813  
          * @param imageName
 814  
          *            the image name to generate a default button name for
 815  
          * @return the default button image url
 816  
          */
 817  
         public static String getDefaultButtonImageUrl(String imageName) {
 818  0
                 return getKualiConfigurationService().getPropertyString(WebUtils.DEFAULT_IMAGE_URL_PROPERTY_NAME)
 819  
                                 + "buttonsmall_" + imageName + ".gif";
 820  
         }
 821  
 
 822  
         /**
 823  
          * @return whether the deploy environment is production
 824  
          */
 825  
         public static boolean isProductionEnvironment() {
 826  0
                 return getKualiConfigurationService().isProductionEnvironment();
 827  
         }
 828  
 
 829  
         /**
 830  
          * @return an implementation of the KualiConfigurationService
 831  
          */
 832  
         public static ConfigurationService getKualiConfigurationService() {
 833  0
                 if (configurationService == null) {
 834  0
                         configurationService = KNSServiceLocator.getKualiConfigurationService();
 835  
                 }
 836  0
                 return configurationService;
 837  
         }
 838  
 
 839  
         /**
 840  
          * Translates the given Map of String keys and String array values to a Map
 841  
          * of String key and values. If the String array contains more than one
 842  
          * value, the single string is built by joining the values with the vertical
 843  
          * bar character
 844  
          * 
 845  
          * @param requestParameters
 846  
          *            - Map of request parameters to translate
 847  
          * @return Map<String, String> translated Map
 848  
          */
 849  
         public static Map<String, String> translateRequestParameterMap(Map<String, String[]> requestParameters) {
 850  0
                 Map<String, String> parameters = new HashMap<String, String>();
 851  
 
 852  0
                 for (Map.Entry<String, String[]> parameter : requestParameters.entrySet()) {
 853  0
                         String parameterValue = "";
 854  0
                         if (parameter.getValue().length > 1) {
 855  0
                                 parameterValue = StringUtils.join(parameter.getValue(), "|");
 856  
                         }
 857  
                         else {
 858  0
                                 parameterValue = parameter.getValue()[0];
 859  
                         }
 860  0
                         parameters.put(parameter.getKey(), parameterValue);
 861  0
                 }
 862  
 
 863  0
                 return parameters;
 864  
         }
 865  
 
 866  
         /**
 867  
          * Retrieves parameter values from the request that match the requested
 868  
          * names. In addition, based on the object class an authorization check is
 869  
          * performed to determine if the values are secure and should be decrypted.
 870  
          * If true, the value is decrypted before returning
 871  
          * 
 872  
          * @param parameterNames
 873  
          *            - names of the parameters whose values should be retrieved
 874  
          *            from the request
 875  
          * @param parentObjectClass
 876  
          *            - object class that contains the parameter names as properties
 877  
          *            and should be consulted for security checks
 878  
          * @param requestParameters
 879  
          *            - all request parameters to pull from
 880  
          * @return Map<String, String> populated with parameter name/value pairs
 881  
          *         pulled from the request
 882  
          */
 883  
         public static Map<String, String> getParametersFromRequest(List<String> parameterNames,
 884  
                         Class<? extends BusinessObject> parentObjectClass, Map<String, String> requestParameters) {
 885  0
                 Map<String, String> parameterValues = new HashMap<String, String>();
 886  
                 
 887  0
                 for (Iterator<String> iter = parameterNames.iterator(); iter.hasNext();) {
 888  0
                         String keyPropertyName = iter.next();
 889  
 
 890  0
                         if (requestParameters.get(keyPropertyName) != null) {
 891  0
                                 String keyValue = requestParameters.get(keyPropertyName);
 892  
 
 893  
                                 // Check if this element was encrypted, if it was decrypt it
 894  0
                                 if (KNSServiceLocatorWeb.getBusinessObjectAuthorizationService()
 895  
                                                 .attributeValueNeedsToBeEncryptedOnFormsAndLinks(parentObjectClass, keyPropertyName)) {
 896  
                                         try {
 897  0
                                                 keyValue = StringUtils.removeEnd(keyValue, EncryptionService.ENCRYPTION_POST_PREFIX);
 898  0
                                                 keyValue = CoreApiServiceLocator.getEncryptionService().decrypt(keyValue);
 899  
                                         }
 900  0
                                         catch (GeneralSecurityException e) {
 901  0
                                                 throw new RuntimeException(e);
 902  0
                                         }
 903  
                                 }
 904  
 
 905  0
                                 parameterValues.put(keyPropertyName, keyValue);
 906  
                         }
 907  0
                 }
 908  
 
 909  0
                 return parameterValues;
 910  
         }
 911  
         
 912  
         /**
 913  
          * Translates characters in the given string like brackets that will cause
 914  
          * problems with binding to characters that do not affect the binding
 915  
          * 
 916  
          * @param key
 917  
          *            - string to translate
 918  
          * @return String translated string
 919  
          */
 920  
         public static String translateToMapSafeKey(String key) {
 921  0
                 String safeKey = key;
 922  
                 
 923  0
                 safeKey = StringUtils.replace(safeKey, "[", "_");
 924  0
                 safeKey = StringUtils.replace(safeKey, "]", "_");
 925  
 
 926  0
                 return safeKey;
 927  
         }
 928  
         
 929  
         /**
 930  
          * Builds a string from the given map by joining each entry with a comma and
 931  
          * each key/value pair with a colon
 932  
          * 
 933  
          * @param map
 934  
          *            - map instance to build string for
 935  
          * @return String of map entries
 936  
          */
 937  
         public static String buildMapParameterString(Map<String, String> map) {
 938  0
                 String parameterString = "";
 939  
 
 940  0
                 for (Entry<String, String> entry : map.entrySet()) {
 941  0
                         if (StringUtils.isNotBlank(parameterString)) {
 942  0
                                 parameterString += ",";
 943  
                         }
 944  
 
 945  0
                         parameterString += entry.getKey() + ":" + entry.getValue();
 946  
                 }
 947  
 
 948  0
                 return parameterString;
 949  
         }
 950  
         
 951  
         /**
 952  
          * Parses the given string into a Map by splitting on the comma to get the
 953  
          * map entries and within each entry splitting by colon to get the key/value
 954  
          * pairs
 955  
          * 
 956  
          * @param parameterString
 957  
          *            - string to parse into map
 958  
          * @return Map<String, String> map from string
 959  
          */
 960  
         public static Map<String, String> getMapFromParameterString(String parameterString) {
 961  0
                 Map<String, String> map = new HashMap<String, String>();
 962  
 
 963  0
                 String[] entries = parameterString.split(".");
 964  0
                 for (int i = 0; i < entries.length; i++) {
 965  0
                         String[] keyValue = entries[i].split(":");
 966  0
                         if (keyValue.length != 2) {
 967  0
                                 throw new RuntimeException("malformed field conversion pair: " + Arrays.toString(keyValue));
 968  
                         }
 969  
 
 970  0
                         map.put(keyValue[0], keyValue[1]);
 971  
                 }
 972  
 
 973  0
                 return map;
 974  
         }
 975  
 
 976  
     /**
 977  
      * Retrieves value for the given parameter name in the request and attempts to convert to a Boolean using
 978  
      * the <code>BooleanFormatter</code>
 979  
      *
 980  
      * @param request - servlet request containing parameters
 981  
      * @param parameterName - name of parameter to retrieve value for
 982  
      * @return Boolean set to value of parameter, or null if parameter was not found in request
 983  
      */
 984  
     public static Boolean getRequestParameterAsBoolean(ServletRequest request, String parameterName) {
 985  0
         Boolean parameterValue = null;
 986  
 
 987  0
         String parameterValueStr = request.getParameter(parameterName);
 988  0
         if (StringUtils.isNotBlank(parameterValueStr)) {
 989  0
             parameterValue = (Boolean) new BooleanFormatter().convertFromPresentationFormat(parameterValueStr);
 990  
         }
 991  
 
 992  0
         return parameterValue;
 993  
     }
 994  
 }