1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
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.util.Arrays;
23  import java.util.Collection;
24  import java.util.Enumeration;
25  import java.util.HashMap;
26  import java.util.Hashtable;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.Set;
31  import java.util.regex.Matcher;
32  import java.util.regex.Pattern;
33  
34  import javax.servlet.ServletException;
35  import javax.servlet.http.HttpServletRequest;
36  import javax.servlet.http.HttpServletResponse;
37  import javax.servlet.http.HttpSession;
38  import javax.servlet.jsp.PageContext;
39  
40  import org.apache.commons.lang.StringEscapeUtils;
41  import org.apache.commons.lang.StringUtils;
42  import org.apache.log4j.Level;
43  import org.apache.log4j.Logger;
44  import org.apache.struts.Globals;
45  import org.apache.struts.action.ActionForm;
46  import org.apache.struts.action.ActionMapping;
47  import org.apache.struts.action.ActionServletWrapper;
48  import org.apache.struts.upload.CommonsMultipartRequestHandler;
49  import org.apache.struts.upload.FormFile;
50  import org.apache.struts.upload.MultipartRequestHandler;
51  import org.apache.struts.upload.MultipartRequestWrapper;
52  import org.kuali.rice.core.api.config.property.ConfigurationService;
53  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
54  import org.kuali.rice.core.api.util.RiceKeyConstants;
55  import org.kuali.rice.kew.api.action.ActionRequest;
56  import org.kuali.rice.kew.api.action.RecipientType;
57  import org.kuali.rice.kim.api.role.Role;
58  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
59  import org.kuali.rice.kns.datadictionary.KNSDocumentEntry;
60  import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry;
61  import org.kuali.rice.kns.document.authorization.DocumentAuthorizer;
62  import org.kuali.rice.kns.service.KNSServiceLocator;
63  import org.kuali.rice.kns.web.struts.action.KualiMultipartRequestHandler;
64  import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
65  import org.kuali.rice.kns.web.struts.form.KualiForm;
66  import org.kuali.rice.kns.web.struts.form.KualiMaintenanceForm;
67  import org.kuali.rice.kns.web.struts.form.pojo.PojoFormBase;
68  import org.kuali.rice.kns.web.ui.Field;
69  import org.kuali.rice.kns.web.ui.Row;
70  import org.kuali.rice.kns.web.ui.Section;
71  import org.kuali.rice.krad.datadictionary.AttributeDefinition;
72  import org.kuali.rice.krad.datadictionary.AttributeSecurity;
73  import org.kuali.rice.krad.datadictionary.DataDictionary;
74  import org.kuali.rice.krad.datadictionary.DataDictionaryEntryBase;
75  import org.kuali.rice.krad.datadictionary.mask.MaskFormatter;
76  import org.kuali.rice.krad.document.Document;
77  import org.kuali.rice.krad.exception.ValidationException;
78  import org.kuali.rice.krad.service.KRADServiceLocator;
79  import org.kuali.rice.krad.service.KRADServiceLocatorInternal;
80  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
81  import org.kuali.rice.krad.util.GlobalVariables;
82  import org.kuali.rice.krad.util.KRADConstants;
83  import org.kuali.rice.krad.util.MessageMap;
84  import org.kuali.rice.krad.util.ObjectUtils;
85  import org.springframework.transaction.PlatformTransactionManager;
86  import org.springframework.transaction.TransactionStatus;
87  import org.springframework.transaction.support.TransactionCallback;
88  import org.springframework.transaction.support.TransactionTemplate;
89  
90  
91  
92  
93  public class WebUtils {
94  	private static final Logger LOG = Logger.getLogger(WebUtils.class);
95  
96  	private static final String IMAGE_COORDINATE_CLICKED_X_EXTENSION = ".x";
97  	private static final String IMAGE_COORDINATE_CLICKED_Y_EXTENSION = ".y";
98  
99  	private static final String APPLICATION_IMAGE_URL_PROPERTY_PREFIX = "application.custom.image.url";
100 	private static final String DEFAULT_IMAGE_URL_PROPERTY_NAME = "kr.externalizable.images.url";
101 
102     
103 
104 
105     private static final String[] SCHEMES = { "http://", "https://" };
106 
107 	
108 
109 
110 
111 
112 	public static final String FILE_UPLOAD_LIMIT_EXCEEDED_EXCEPTION_ALREADY_THROWN = "fileUploadLimitExceededExceptionAlreadyThrown";
113 
114 	private static ConfigurationService configurationService;
115     private static PlatformTransactionManager transactionManager;
116 
117 	
118 
119 
120 
121 
122 
123 
124 	public static String parseMethodToCall(ActionForm form, HttpServletRequest request) {
125 		String methodToCall = null;
126 
127 		
128 		if (StringUtils.isNotBlank(request.getParameter(KRADConstants.DISPATCH_REQUEST_PARAMETER))) {
129 			if (form instanceof KualiForm
130 					&& !((KualiForm) form).shouldMethodToCallParameterBeUsed(KRADConstants.DISPATCH_REQUEST_PARAMETER,
131 							request.getParameter(KRADConstants.DISPATCH_REQUEST_PARAMETER), request)) {
132 				throw new RuntimeException("Cannot verify that the methodToCall should be "
133 						+ request.getParameter(KRADConstants.DISPATCH_REQUEST_PARAMETER));
134 			}
135 			methodToCall = request.getParameter(KRADConstants.DISPATCH_REQUEST_PARAMETER);
136 			
137 			
138 			request.setAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE, KRADConstants.DISPATCH_REQUEST_PARAMETER + "."
139 					+ methodToCall + IMAGE_COORDINATE_CLICKED_X_EXTENSION);
140 		}
141 
142 		
143 
144 
145 
146 
147 
148 
149 
150 
151 		if (methodToCall == null) {
152 			
153 			for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) {
154 				String parameterName = (String) i.nextElement();
155 
156 				
157 				if (isMethodToCall(parameterName)) {
158 					methodToCall = getMethodToCallSettingAttribute(form, request, parameterName);
159 					break;
160 				}
161 				else {
162 					
163 					
164 					for (String value : request.getParameterValues(parameterName)) {
165 						
166 						
167 						if (isMethodToCall(value)) {
168 							methodToCall = getMethodToCallSettingAttribute(form, request, value);
169 							
170 						}
171 					}
172 				}
173 			}
174 		}
175 
176 		return methodToCall;
177 	}
178 
179     
180 
181 
182 
183 
184 
185 
186 	private static boolean isMethodToCall(String string) {
187 		
188 		
189 		return string.startsWith(KRADConstants.DISPATCH_REQUEST_PARAMETER + ".");
190 	}
191 
192 	
193 
194 
195 
196 
197 
198 
199 
200 
201 
202 
203 
204 	private static String getMethodToCallSettingAttribute(ActionForm form, HttpServletRequest request, String string) {
205 
206 		if (form instanceof KualiForm
207 				&& !((KualiForm) form).shouldMethodToCallParameterBeUsed(string, request.getParameter(string), request)) {
208 			throw new RuntimeException("Cannot verify that the methodToCall should be " + string);
209 		}
210 		
211 		final String attributeValue = endsWithCoordinates(string) ? string : string
212 				+ IMAGE_COORDINATE_CLICKED_X_EXTENSION;
213 		final String methodToCall = StringUtils.substringBetween(attributeValue,
214 				KRADConstants.DISPATCH_REQUEST_PARAMETER + ".", ".");
215 		request.setAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE, attributeValue);
216 		return methodToCall;
217 	}
218 
219 	
220 
221 
222 
223 
224 
225 
226 	public static void logRequestContents(Logger logger, Level level, HttpServletRequest request) {
227 		if (logger.isEnabledFor(level)) {
228 			logger.log(level, "--------------------");
229 			logger.log(level, "HttpRequest attributes:");
230 			for (Enumeration e = request.getAttributeNames(); e.hasMoreElements();) {
231 				String attrName = (String) e.nextElement();
232 				Object attrValue = request.getAttribute(attrName);
233 
234 				if (attrValue.getClass().isArray()) {
235 					logCollection(logger, level, attrName, Arrays.asList((Object[]) attrValue));
236 				}
237 				else if (attrValue instanceof Collection) {
238 					logCollection(logger, level, attrName, (Collection) attrValue);
239 				}
240 				else if (attrValue instanceof Map) {
241 					logMap(logger, level, attrName, (Map) attrValue);
242 				}
243 				else {
244 					logObject(logger, level, attrName, attrValue);
245 				}
246 			}
247 
248 			logger.log(level, "--------------------");
249 			logger.log(level, "HttpRequest parameters:");
250 			for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) {
251 				String paramName = (String) i.nextElement();
252 				String[] paramValues = request.getParameterValues(paramName);
253 
254 				logArray(logger, level, paramName, paramValues);
255 			}
256 
257 			logger.log(level, "--------------------");
258 		}
259 	}
260 
261 	private static void logArray(Logger logger, Level level, String arrayName, Object[] array) {
262 		StringBuffer value = new StringBuffer("[");
263 		for (int i = 0; i < array.length; ++i) {
264 			if (i > 0) {
265 				value.append(",");
266 			}
267 			value.append(array[i]);
268 		}
269 		value.append("]");
270 
271 		logThing(logger, level, arrayName, value);
272 	}
273 
274 	private static void logCollection(Logger logger, Level level, String collectionName, Collection c) {
275 		StringBuffer value = new StringBuffer("{");
276 		for (Iterator i = c.iterator(); i.hasNext();) {
277 			value.append(i.next());
278 			if (i.hasNext()) {
279 				value.append(",");
280 			}
281 		}
282 		value.append("}");
283 
284 		logThing(logger, level, collectionName, value);
285 	}
286 
287 	private static void logMap(Logger logger, Level level, String mapName, Map m) {
288 		StringBuffer value = new StringBuffer("{");
289 		for (Iterator i = m.entrySet().iterator(); i.hasNext();) {
290 			Map.Entry e = (Map.Entry) i.next();
291 			value.append("('" + e.getKey() + "','" + e.getValue() + "')");
292 		}
293 		value.append("}");
294 
295 		logThing(logger, level, mapName, value);
296 	}
297 
298 	private static void logObject(Logger logger, Level level, String objectName, Object o) {
299 		logThing(logger, level, objectName, "'" + o + "'");
300 	}
301 
302 	private static void logThing(Logger logger, Level level, String thingName, Object thing) {
303 		logger.log(level, "    '" + thingName + "' => " + thing);
304 	}
305 
306 	
307 
308 
309 
310 
311 
312 
313 
314 
315 	public static void saveMimeOutputStreamAsFile(HttpServletResponse response, String contentType,
316 			ByteArrayOutputStream byteArrayOutputStream, String fileName) throws IOException {
317 
318 		
319 		response.setContentType(contentType);
320 		response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
321 		response.setHeader("Expires", "0");
322 		response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
323 		response.setHeader("Pragma", "public");
324 		response.setContentLength(byteArrayOutputStream.size());
325 
326 		
327 		OutputStream outputStream = response.getOutputStream();
328 		byteArrayOutputStream.writeTo(response.getOutputStream());
329 		outputStream.flush();
330 		outputStream.close();
331 	}
332 
333 	
334 
335 
336 
337 
338 
339 
340 
341 
342 	public static void saveMimeInputStreamAsFile(HttpServletResponse response, String contentType,
343 			InputStream inStream, String fileName, int fileSize) throws IOException {
344 
345 		
346 		response.setContentType(contentType);
347 		response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
348 		response.setHeader("Expires", "0");
349 		response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
350 		response.setHeader("Pragma", "public");
351 		response.setContentLength(fileSize);
352 
353 		
354 		OutputStream out = response.getOutputStream();
355 		while (inStream.available() > 0) {
356 			out.write(inStream.read());
357 		}
358 		out.flush();
359 	}
360 
361 	
362 
363 
364 
365 
366 
367 
368 	public static String getTabState(KualiForm form, String tabKey) {
369 		return form.getTabState(tabKey);
370 	}
371 
372 	public static void incrementTabIndex(KualiForm form, String tabKey) {
373 		form.incrementTabIndex();
374 	}
375 
376     
377 
378 
379 
380 
381 
382 
383     public static void reopenInactiveRecords(List<Section> sections, Map<String, String> tabStates, String collectionName) {
384         for (Section section : sections) {
385             for (Row row: section.getRows()) {
386                 for (Field field : row.getFields()) {
387                     if (field != null) {
388                         if (Field.CONTAINER.equals(field.getFieldType()) && StringUtils.startsWith(field.getContainerName(), collectionName)) {
389                             final String tabKey = WebUtils.generateTabKey(FieldUtils.generateCollectionSubTabName(field));
390                             tabStates.put(tabKey, KualiForm.TabState.OPEN.name());
391                         }
392                     }
393                 }
394             }
395         }
396     }
397 
398 	
399 
400 
401 
402 
403 
404 	public static String generateTabKey(String tabTitle) {
405 		String key = "";
406 		if (!StringUtils.isBlank(tabTitle)) {
407 			key = tabTitle.replaceAll("\\W", "");
408 			
409 			
410 			
411 		}
412 
413 		return key;
414 	}
415 
416 	public static void getMultipartParameters(HttpServletRequest request, ActionServletWrapper servletWrapper,
417 			ActionForm form, ActionMapping mapping) {
418 		Map params = new HashMap();
419 
420 		
421 		
422 
423 		try {
424 			CommonsMultipartRequestHandler multipartHandler = new CommonsMultipartRequestHandler();
425 			if (multipartHandler != null) {
426 				
427 				if (servletWrapper != null) {
428 					
429 					
430 					servletWrapper.setServletFor(multipartHandler);
431 				}
432 				multipartHandler.setMapping((ActionMapping) request.getAttribute(Globals.MAPPING_KEY));
433 				
434 				multipartHandler.handleRequest(request);
435 
436 				Collection<FormFile> files = multipartHandler.getFileElements().values();
437 				Enumeration keys = multipartHandler.getFileElements().keys();
438 
439 				while (keys.hasMoreElements()) {
440 					Object key = keys.nextElement();
441 					FormFile file = (FormFile) multipartHandler.getFileElements().get(key);
442 					long maxSize = WebUtils.getMaxUploadSize(form);
443 					if (LOG.isDebugEnabled()) {
444 						LOG.debug(file.getFileSize());
445 					}
446 					if (maxSize > 0 && Long.parseLong(file.getFileSize() + "") > maxSize) {
447 
448 						GlobalVariables.getMessageMap().putError(key.toString(),
449 								RiceKeyConstants.ERROR_UPLOADFILE_SIZE,
450 								new String[] { file.getFileName(), Long.toString(maxSize) });
451 
452 					}
453 				}
454 
455 				
456 				if (servletWrapper == null) {
457 					request.setAttribute(KRADConstants.UPLOADED_FILE_REQUEST_ATTRIBUTE_KEY,
458 							getFileParametersForMultipartRequest(request, multipartHandler));
459 				}
460 			}
461 		}
462 		catch (ServletException e) {
463 			throw new ValidationException("unable to handle multipart request " + e.getMessage(), e);
464 		}
465 	}
466 
467 	public static long getMaxUploadSize(ActionForm form) {
468 		long max = 0L;
469 		KualiMultipartRequestHandler multipartHandler = new KualiMultipartRequestHandler();
470 		if (form instanceof PojoFormBase) {
471 			max = multipartHandler.calculateMaxUploadSizeToMaxOfList(((PojoFormBase) form).getMaxUploadSizes());
472 		}
473 		if (LOG.isDebugEnabled()) {
474 			LOG.debug("Max File Upload Size: " + max);
475 		}
476 		return max;
477 	}
478 
479 	private static Map getFileParametersForMultipartRequest(HttpServletRequest request,
480 			MultipartRequestHandler multipartHandler) {
481 		Map parameters = new HashMap();
482 		Hashtable elements = multipartHandler.getFileElements();
483 		Enumeration e = elements.keys();
484 		while (e.hasMoreElements()) {
485 			String key = (String) e.nextElement();
486 			parameters.put(key, elements.get(key));
487 		}
488 
489 		if (request instanceof MultipartRequestWrapper) {
490 			request = (HttpServletRequest) ((MultipartRequestWrapper) request).getRequest();
491 			e = request.getParameterNames();
492 			while (e.hasMoreElements()) {
493 				String key = (String) e.nextElement();
494 				parameters.put(key, request.getParameterValues(key));
495 			}
496 		}
497 		else {
498 			LOG.debug("Gathering multipart parameters for unwrapped request");
499 		}
500 		return parameters;
501 	}
502 
503 	
504 
505 	public static void registerEditableProperty(PojoFormBase form, String editablePropertyName) {
506 		form.registerEditableProperty(editablePropertyName);
507 	}
508 
509 	public static boolean isDocumentSession(Document document, PojoFormBase docForm) {
510 		boolean sessionDoc = document instanceof org.kuali.rice.krad.document.SessionDocument;
511 		boolean dataDictionarySessionDoc = false;
512 		if (!sessionDoc) {
513 			DataDictionary dataDictionary = KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary();
514 			if (docForm instanceof KualiMaintenanceForm) {
515 				KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) docForm;
516 				if (dataDictionary != null) {
517 					if (maintenanceForm.getDocTypeName() != null) {
518                         MaintenanceDocumentEntry maintenanceDocumentEntry = (MaintenanceDocumentEntry) dataDictionary.getDocumentEntry(maintenanceForm.getDocTypeName());
519 						dataDictionarySessionDoc = maintenanceDocumentEntry.isSessionDocument();
520 					}
521 				}
522 			}
523 			else {
524 				if (document != null && dataDictionary != null) {
525 					KNSDocumentEntry documentEntry = (KNSDocumentEntry) dataDictionary.getDocumentEntry(document.getClass().getName());
526 					dataDictionarySessionDoc = documentEntry.isSessionDocument();
527 				}
528 			}
529 		}
530 		return sessionDoc || dataDictionarySessionDoc;
531 	}
532 
533 	public static boolean isFormSessionDocument(PojoFormBase form) {
534 		Document document = null;
535 		if (KualiDocumentFormBase.class.isAssignableFrom(form.getClass())) {
536 			KualiDocumentFormBase docForm = (KualiDocumentFormBase) form;
537 			document = docForm.getDocument();
538 		}
539 		return isDocumentSession(document, form);
540 	}
541 
542 	public static String KEY_KUALI_FORM_IN_SESSION = "KualiForm";
543 
544 	public static ActionForm getKualiForm(PageContext pageContext) {
545 		return getKualiForm((HttpServletRequest) pageContext.getRequest());
546 	}
547 
548 	public static ActionForm getKualiForm(HttpServletRequest request) {
549 		if (request.getAttribute(KEY_KUALI_FORM_IN_SESSION) != null) {
550 			return (ActionForm) request.getAttribute(KEY_KUALI_FORM_IN_SESSION);
551 		}
552 		else {
553 			final HttpSession session = request.getSession(false);
554 			return session != null ? (ActionForm) session.getAttribute(KEY_KUALI_FORM_IN_SESSION) : null;
555 		}
556 	}
557 
558 	public static boolean isPropertyEditable(Set<String> editableProperties, String propertyName) {
559 		if (LOG.isDebugEnabled()) {
560 			LOG.debug("isPropertyEditable(" + propertyName + ")");
561 		}
562 
563 		boolean returnVal = editableProperties == null
564 				|| editableProperties.contains(propertyName)
565 				|| (getIndexOfCoordinateExtension(propertyName) == -1 ? false : editableProperties
566 						.contains(propertyName.substring(0, getIndexOfCoordinateExtension(propertyName))));
567 		if (!returnVal) {
568 			if (LOG.isDebugEnabled()) {
569 				LOG.debug("isPropertyEditable(" + propertyName + ") == false / editableProperties: "
570 						+ editableProperties);
571 			}
572 		}
573 		return returnVal;
574 	}
575 
576 	public static boolean endsWithCoordinates(String parameter) {
577 		return parameter.endsWith(WebUtils.IMAGE_COORDINATE_CLICKED_X_EXTENSION)
578 				|| parameter.endsWith(WebUtils.IMAGE_COORDINATE_CLICKED_Y_EXTENSION);
579 	}
580 
581 	public static int getIndexOfCoordinateExtension(String parameter) {
582 		int indexOfCoordinateExtension = parameter.lastIndexOf(WebUtils.IMAGE_COORDINATE_CLICKED_X_EXTENSION);
583         if (indexOfCoordinateExtension == -1) {
584             indexOfCoordinateExtension = parameter.lastIndexOf(WebUtils.IMAGE_COORDINATE_CLICKED_Y_EXTENSION);
585         }
586 		return indexOfCoordinateExtension;
587 	}
588 
589     public static boolean isInquiryHiddenField(String className, String fieldName, Object formObject, String propertyName) {
590     	boolean isHidden = false;
591     	String hiddenInquiryFields = getKualiConfigurationService().getPropertyValueAsString(className + ".hidden");
592     	if (StringUtils.isEmpty(hiddenInquiryFields)) {
593     		return isHidden;
594     	}
595     	List hiddenFields = Arrays.asList(hiddenInquiryFields.replaceAll(" ", "").split(","));
596     	if (hiddenFields.contains(fieldName.trim())) {
597     		isHidden = true;
598     	}
599     	return isHidden;
600     }
601 
602     public static boolean isHiddenKimObjectType(String type, String configParameter) {
603     	boolean hideType = false;
604     	String hiddenTypes = getKualiConfigurationService().getPropertyValueAsString(configParameter);
605     	if (StringUtils.isEmpty(hiddenTypes)) {
606     		return hideType;
607     	}
608     	List hiddenTypeValues = Arrays.asList(hiddenTypes.replaceAll(" ", "").split(","));
609     	if (hiddenTypeValues.contains(type.trim())) {
610     		hideType = true;
611     	}
612     	return hideType;
613     }
614 
615 	public static String getFullyMaskedValue(String className, String fieldName, Object formObject, String propertyName) {
616 		String displayMaskValue = null;
617 		Object propertyValue = ObjectUtils.getPropertyValue(formObject, propertyName);
618 
619 		DataDictionaryEntryBase entry = (DataDictionaryEntryBase) KRADServiceLocatorWeb.getDataDictionaryService()
620 				.getDataDictionary().getDictionaryObjectEntry(className);
621 		AttributeDefinition a = entry.getAttributeDefinition(fieldName);
622 
623 		AttributeSecurity attributeSecurity = a.getAttributeSecurity();
624 		if (attributeSecurity != null && attributeSecurity.isMask()) {
625 			MaskFormatter maskFormatter = attributeSecurity.getMaskFormatter();
626 			displayMaskValue = maskFormatter.maskValue(propertyValue);
627 
628 		}
629 		return displayMaskValue;
630 	}
631 
632 	public static String getPartiallyMaskedValue(String className, String fieldName, Object formObject,
633 			String propertyName) {
634 		String displayMaskValue = null;
635 		Object propertyValue = ObjectUtils.getPropertyValue(formObject, propertyName);
636 
637 		DataDictionaryEntryBase entry = (DataDictionaryEntryBase) KRADServiceLocatorWeb.getDataDictionaryService()
638 				.getDataDictionary().getDictionaryObjectEntry(className);
639 		AttributeDefinition a = entry.getAttributeDefinition(fieldName);
640 
641 		AttributeSecurity attributeSecurity = a.getAttributeSecurity();
642 		if (attributeSecurity != null && attributeSecurity.isPartialMask()) {
643 			MaskFormatter partialMaskFormatter = attributeSecurity.getPartialMaskFormatter();
644 			displayMaskValue = partialMaskFormatter.maskValue(propertyValue);
645 
646 		}
647 		return displayMaskValue;
648 	}
649 
650 	public static boolean canFullyUnmaskField(final String businessObjectClassName, final String fieldName, final KualiForm form) {
651 		try {
652 		    final Class businessObjClass = Class.forName(businessObjectClassName);
653 	        TransactionTemplate template = new TransactionTemplate(getTransactionManager());
654 	        return template.execute(new TransactionCallback<Boolean>() {
655 	            @Override
656 	            public Boolean doInTransaction(TransactionStatus status) {
657 	                if (form instanceof KualiDocumentFormBase) {
658 	                    return KNSServiceLocator.getBusinessObjectAuthorizationService().canFullyUnmaskField(
659 	                            GlobalVariables.getUserSession().getPerson(), businessObjClass, fieldName,
660 	                            ((KualiDocumentFormBase) form).getDocument());
661 	                }
662 	                else {
663 	                    return KNSServiceLocator.getBusinessObjectAuthorizationService().canFullyUnmaskField(
664 	                            GlobalVariables.getUserSession().getPerson(), businessObjClass, fieldName, null);
665 	                }
666 	            }
667 	        });
668 		}
669 		catch (Exception e) {
670 			throw new RuntimeException("Unable to resolve class name: " + businessObjectClassName);
671 		}
672 	}
673 
674 	public static boolean canPartiallyUnmaskField(String businessObjectClassName, final String fieldName, final KualiForm form) {
675 		try {
676 			final Class businessObjClass = Class.forName(businessObjectClassName);
677 	        TransactionTemplate template = new TransactionTemplate(getTransactionManager());
678 	        return template.execute(new TransactionCallback<Boolean>() {
679 	            @Override
680 	            public Boolean doInTransaction(TransactionStatus status) {
681 	                if (form instanceof KualiDocumentFormBase) {
682 	                    return KNSServiceLocator.getBusinessObjectAuthorizationService().canPartiallyUnmaskField(
683 	                            GlobalVariables.getUserSession().getPerson(), businessObjClass, fieldName,
684 	                            ((KualiDocumentFormBase) form).getDocument());
685 	                }
686 	                else {
687 	                    return KNSServiceLocator.getBusinessObjectAuthorizationService().canPartiallyUnmaskField(
688 	                            GlobalVariables.getUserSession().getPerson(), businessObjClass, fieldName, null);
689 	                }
690 	            }
691 	        });
692 		}
693 		catch (Exception e) {
694 			throw new RuntimeException("Unable to resolve class name: " + businessObjectClassName);
695 		}
696 	}
697 
698 	public static boolean canAddNoteAttachment(final Document document) {
699         TransactionTemplate template = new TransactionTemplate(getTransactionManager());
700         return template.execute(new TransactionCallback<Boolean>() {
701             @Override
702             public Boolean doInTransaction(TransactionStatus status) {
703                 boolean canViewNoteAttachment = false;
704                 DocumentAuthorizer documentAuthorizer = KNSServiceLocator.getDocumentHelperService().getDocumentAuthorizer(
705                         document);
706                 canViewNoteAttachment = documentAuthorizer.canAddNoteAttachment(document, null, GlobalVariables
707                         .getUserSession().getPerson());
708                 return canViewNoteAttachment;
709             }
710         });
711 	}
712 
713 	public static boolean canViewNoteAttachment(final Document document, final String attachmentTypeCode) {
714         TransactionTemplate template = new TransactionTemplate(getTransactionManager());
715         return template.execute(new TransactionCallback<Boolean>() {
716             @Override
717             public Boolean doInTransaction(TransactionStatus status) {
718                 boolean canViewNoteAttachment = false;
719                 DocumentAuthorizer documentAuthorizer = KNSServiceLocator.getDocumentHelperService().getDocumentAuthorizer(
720                         document);
721                 canViewNoteAttachment = documentAuthorizer.canViewNoteAttachment(document, attachmentTypeCode, GlobalVariables
722                         .getUserSession().getPerson());
723                 return canViewNoteAttachment;
724             }
725         });
726 	}
727 
728 	public static boolean canDeleteNoteAttachment(final Document document, final String attachmentTypeCode, final String authorUniversalIdentifier) {
729         TransactionTemplate template = new TransactionTemplate(getTransactionManager());
730         return template.execute(new TransactionCallback<Boolean>() {
731             @Override
732             public Boolean doInTransaction(TransactionStatus status) {
733                 boolean canDeleteNoteAttachment = false;
734                 DocumentAuthorizer documentAuthorizer = KNSServiceLocator.getDocumentHelperService().getDocumentAuthorizer(
735                         document);
736                 canDeleteNoteAttachment = documentAuthorizer.canDeleteNoteAttachment(document, attachmentTypeCode, "false",
737                         GlobalVariables.getUserSession().getPerson());
738                 if (canDeleteNoteAttachment) {
739                     return canDeleteNoteAttachment;
740                 }
741                 else {
742                     canDeleteNoteAttachment = documentAuthorizer.canDeleteNoteAttachment(document, attachmentTypeCode, "true",
743                             GlobalVariables.getUserSession().getPerson());
744                     if (canDeleteNoteAttachment
745                             && !authorUniversalIdentifier.equals(GlobalVariables.getUserSession().getPerson().getPrincipalId())) {
746                         canDeleteNoteAttachment = false;
747                     }
748                 }
749                 return canDeleteNoteAttachment;
750             }
751         });
752 	}
753 
754 	public static void reuseErrorMapFromPreviousRequest(KualiDocumentFormBase kualiDocumentFormBase) {
755 		if (kualiDocumentFormBase.getMessageMapFromPreviousRequest() == null) {
756 			LOG.error("Error map from previous request is null!");
757 			return;
758 		}
759 		MessageMap errorMapFromGlobalVariables = GlobalVariables.getMessageMap();
760 		if (kualiDocumentFormBase.getMessageMapFromPreviousRequest() == errorMapFromGlobalVariables) {
761 			
762 			return;
763 		}
764 		if (!errorMapFromGlobalVariables.hasNoErrors()) {
765 			throw new RuntimeException("Cannot replace error map because it is not empty");
766 		}
767 		GlobalVariables.setMessageMap(kualiDocumentFormBase.getMessageMapFromPreviousRequest());
768 		GlobalVariables.getMessageMap().clearErrorPath();
769 	}
770 
771 	
772 
773 
774 
775 
776 
777 
778 
779 
780 
781 
782 
783 
784 
785 
786 
787 
788 	public static String filterHtmlAndReplaceRiceMarkup(String inputString) {
789 		String outputString = StringEscapeUtils.escapeHtml(inputString);
790 		
791 
792 		Map<String, String> findAndReplacePatterns = new HashMap<String, String>();
793 
794 		
795 
796 		
797 
798 		
799 		findAndReplacePatterns.put("\\[([A-Za-z])\\]", "<$1>");
800 		findAndReplacePatterns.put("\\[/([A-Za-z])\\]", "</$1>");
801 		
802 		findAndReplacePatterns.put("\\[([A-Za-z]{2})\\]", "<$1>");
803 		findAndReplacePatterns.put("\\[/([A-Za-z]{2})\\]", "</$1>");
804 		
805 		findAndReplacePatterns.put("\\[font (#[0-9A-Fa-f]{1,6}|[A-Za-z]+)\\]", "<font color=\"$1\">");
806 		findAndReplacePatterns.put("\\[/font\\]", "</font>");
807 		
808 		findAndReplacePatterns.put("\\[table\\]", "<table>");
809 		findAndReplacePatterns.put("\\[table ([A-Za-z]+)\\]", "<table class=\"$1\">");
810 		findAndReplacePatterns.put("\\[/table\\]", "</table>");
811 		
812 		findAndReplacePatterns.put("\\[td ([A-Za-z]+)\\]", "<td class=\"$1\">");
813 
814 		for (String findPattern : findAndReplacePatterns.keySet()) {
815 			Pattern p = Pattern.compile(findPattern);
816 			Matcher m = p.matcher(outputString);
817 			if (m.find()) {
818 				String replacePattern = findAndReplacePatterns.get(findPattern);
819 				outputString = m.replaceAll(replacePattern);
820 			}
821 		}
822 
823 		return outputString;
824 	}
825 
826     
827 
828 
829 
830 
831 
832 
833 
834 
835 	public static String getButtonImageUrl(String imageName) {
836 		String buttonImageUrl = getKualiConfigurationService().getPropertyValueAsString(
837                 WebUtils.APPLICATION_IMAGE_URL_PROPERTY_PREFIX + "." + imageName);
838 		if (StringUtils.isBlank(buttonImageUrl)) {
839 			buttonImageUrl = getDefaultButtonImageUrl(imageName);
840 		}
841 		return buttonImageUrl;
842 	}
843 
844     public static String getAttachmentImageForUrl(String contentType) {
845         String image = getKualiConfigurationService().getPropertyValueAsString(KRADConstants.ATTACHMENT_IMAGE_PREFIX + contentType);
846         if (StringUtils.isEmpty(image)) {
847             return getKualiConfigurationService().getPropertyValueAsString(KRADConstants.ATTACHMENT_IMAGE_DEFAULT);
848         }
849         return image;
850     }
851 
852 	
853 
854 
855 
856 
857 
858 
859 
860 	public static String getDefaultButtonImageUrl(String imageName) {
861 		return getKualiConfigurationService().getPropertyValueAsString(WebUtils.DEFAULT_IMAGE_URL_PROPERTY_NAME)
862 				+ "buttonsmall_" + imageName + ".gif";
863 	}
864 
865     
866 
867 
868 	public static ConfigurationService getKualiConfigurationService() {
869 		if (configurationService == null) {
870 			configurationService = GlobalResourceLoader.getService("kualiConfigurationService");
871 		}
872 		return configurationService;
873 	}
874     public static PlatformTransactionManager getTransactionManager() {
875         if ( transactionManager == null ) {
876             transactionManager = GlobalResourceLoader.getService("transactionManager");
877         }
878         return transactionManager;
879     }
880 
881     
882 
883 
884 
885 
886 
887 
888     public static String preserveWhitespace(String startingString) {
889     	String convertedString = startingString.replaceAll("\n", "<br />");
890     	convertedString = convertedString.replaceAll("  ", "  ").replaceAll("(  |  )", "  ");
891     	return convertedString;
892     }
893 
894     public static String getKimGroupDisplayName(final String groupId) {
895     	if(StringUtils.isBlank(groupId)) {
896     		throw new IllegalArgumentException("Group ID must have a value");
897     	}
898         TransactionTemplate template = new TransactionTemplate(getTransactionManager());
899         return template.execute(new TransactionCallback<String>() {
900             @Override
901             public String doInTransaction(TransactionStatus status) {
902                 return KimApiServiceLocator.getGroupService().getGroup(groupId).getName();
903             }
904         });
905     }
906 
907     public static String getPrincipalDisplayName(final String principalId) {
908     	if(StringUtils.isBlank(principalId)) {
909     		throw new IllegalArgumentException("Principal ID must have a value");
910     	}
911         TransactionTemplate template = new TransactionTemplate(getTransactionManager());
912         return template.execute(new TransactionCallback<String>() {
913             @Override
914             public String doInTransaction(TransactionStatus status) {
915                 return KimApiServiceLocator.getIdentityService().getDefaultNamesForPrincipalId(principalId).getDefaultName().getCompositeName();
916             }
917         });
918     }
919 
920     
921 
922 
923 
924 
925 
926 
927 
928     public static String getRoleDisplayName(final ActionRequest actionRequest) {
929         if(actionRequest == null) {
930             throw new IllegalArgumentException("actionRequest must be non-null");
931         }
932         if (RecipientType.ROLE != actionRequest.getRecipientType()) {
933             throw new IllegalArgumentException("actionRequest recipient must be a Role");
934         }
935         TransactionTemplate template = new TransactionTemplate(getTransactionManager());
936         return template.execute(new TransactionCallback<String>() {
937             @Override
938             public String doInTransaction(TransactionStatus status) {
939                 String result = "";
940                 Role role = KimApiServiceLocator.getRoleService().getRole(actionRequest.getRoleName());
941 
942                 if (role != null) {
943                     result = role.getName();
944                 } else if (!StringUtils.isBlank(actionRequest.getQualifiedRoleNameLabel())) {
945                     result = actionRequest.getQualifiedRoleNameLabel();
946                 } else {
947                     result = actionRequest.getRoleName();
948                 }
949 
950                 return result;
951             }
952         });
953     }
954 
955     
956 
957 
958 
959 
960 
961 
962     public static String toAbsoluteURL(String base, String path) {
963         boolean abs = false;
964         if (StringUtils.isBlank(path)) {
965             path = "";
966         } else {
967             for (String scheme: SCHEMES) {
968                 if (path.startsWith(scheme)) {
969                     abs = true;
970                     break;
971                 }
972             }
973         }
974         if (abs) {
975             return path;
976         }
977         return base + path;
978     }
979 
980 }