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