1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.util;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.lang.annotation.Annotation;
21 import java.lang.reflect.Constructor;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.net.MalformedURLException;
25 import java.net.URL;
26 import java.security.GeneralSecurityException;
27 import java.text.MessageFormat;
28 import java.text.NumberFormat;
29 import java.text.ParseException;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Properties;
39 import java.util.regex.Pattern;
40
41 import javax.servlet.ServletRequest;
42 import javax.servlet.http.HttpServletRequest;
43 import javax.servlet.http.HttpServletResponse;
44
45 import org.apache.commons.beanutils.PropertyUtils;
46 import org.apache.commons.codec.EncoderException;
47 import org.apache.commons.codec.net.URLCodec;
48 import org.apache.commons.lang.StringUtils;
49 import org.apache.log4j.Logger;
50 import org.kuali.rice.core.api.CoreApiServiceLocator;
51 import org.kuali.rice.core.api.encryption.EncryptionService;
52 import org.kuali.rice.core.api.search.SearchOperator;
53 import org.kuali.rice.core.api.util.RiceKeyConstants;
54 import org.kuali.rice.core.api.util.Truth;
55 import org.kuali.rice.core.api.util.type.KualiDecimal;
56 import org.kuali.rice.core.api.util.type.TypeUtils;
57 import org.kuali.rice.core.web.format.BooleanFormatter;
58 import org.kuali.rice.core.web.format.FormatException;
59 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
60 import org.kuali.rice.coreservice.framework.parameter.ParameterConstants;
61 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
62 import org.kuali.rice.krad.UserSession;
63 import org.kuali.rice.krad.data.KradDataServiceLocator;
64 import org.kuali.rice.krad.messages.MessageService;
65 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
66 import org.kuali.rice.krad.service.KualiModuleService;
67 import org.kuali.rice.krad.service.ModuleService;
68 import org.kuali.rice.krad.uif.UifConstants;
69 import org.kuali.rice.krad.uif.UifParameters;
70 import org.kuali.rice.krad.uif.component.ClientSideState;
71 import org.kuali.rice.krad.uif.component.Component;
72 import org.kuali.rice.krad.uif.element.Action;
73 import org.kuali.rice.krad.uif.element.Image;
74 import org.kuali.rice.krad.uif.element.Link;
75 import org.kuali.rice.krad.uif.field.ActionField;
76 import org.kuali.rice.krad.uif.field.DataField;
77 import org.kuali.rice.krad.uif.field.Field;
78 import org.kuali.rice.krad.uif.field.FieldGroup;
79 import org.kuali.rice.krad.uif.field.ImageField;
80 import org.kuali.rice.krad.uif.field.LinkField;
81 import org.kuali.rice.krad.uif.field.MessageField;
82 import org.kuali.rice.krad.uif.field.SpaceField;
83 import org.kuali.rice.krad.uif.util.CopyUtils;
84 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
85 import org.kuali.rice.krad.uif.util.ViewModelUtils;
86 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
87 import org.kuali.rice.krad.uif.view.View;
88 import org.kuali.rice.krad.web.form.UifFormBase;
89 import org.springframework.beans.PropertyAccessorUtils;
90 import org.springframework.util.Assert;
91 import org.springframework.util.FileCopyUtils;
92
93
94
95
96
97
98 public final class KRADUtils {
99 private static final Logger LOG = Logger.getLogger(KRADUtils.class);
100
101 private static KualiModuleService kualiModuleService;
102 private static final KualiDecimal ONE_HUNDRED = new KualiDecimal("100.00");
103
104
105
106
107 private KRADUtils() {
108 throw new UnsupportedOperationException("do not call");
109 }
110
111
112
113
114
115
116
117
118
119
120
121 public final static String getBusinessTitleForClass(Class<? extends Object> clazz) {
122 if (clazz == null) {
123 throw new IllegalArgumentException(
124 "The getBusinessTitleForClass method of KRADUtils requires a non-null class");
125 }
126 String className = clazz.getSimpleName();
127
128 StringBuffer label = new StringBuffer(className.substring(0, 1));
129 for (int i = 1; i < className.length(); i++) {
130 if (Character.isLowerCase(className.charAt(i))) {
131 label.append(className.charAt(i));
132 } else {
133 label.append(" ").append(className.charAt(i));
134 }
135 }
136 return label.toString().trim();
137 }
138
139
140
141
142
143
144
145
146
147
148
149 public final static List<String> getFileNameFromPath(List<String> fullFileNames) {
150 List<String> fileNameList = new ArrayList<String>();
151
152 for (String fullFileName : fullFileNames) {
153 if (StringUtils.contains(fullFileName, "/")) {
154 fileNameList.add(StringUtils.substringAfterLast(fullFileName, "/"));
155 } else {
156 fileNameList.add(StringUtils.substringAfterLast(fullFileName, "\\"));
157 }
158 }
159
160 return fileNameList;
161 }
162
163
164
165
166
167
168
169
170
171
172
173
174
175 public final static String convertDecimalIntoInteger(KualiDecimal decimalNumber) {
176 KualiDecimal decimalAmount = decimalNumber.multiply(ONE_HUNDRED);
177 NumberFormat formatter = NumberFormat.getIntegerInstance();
178 String formattedAmount = formatter.format(decimalAmount);
179
180 return StringUtils.replace(formattedAmount, ",", "");
181 }
182
183
184
185
186
187
188
189
190
191
192
193 public static Integer getIntegerValue(String numberStr) {
194 Integer numberInt = null;
195 try {
196 numberInt = new Integer(numberStr);
197 } catch (NumberFormatException nfe) {
198 Double numberDbl = new Double(numberStr);
199 numberInt = new Integer(numberDbl.intValue());
200 }
201 return numberInt;
202 }
203
204
205
206
207
208
209
210
211
212
213 public static Object hydrateAttributeValue(Class<?> propertyType, String attributeValue) {
214 Object attributeValueObject = null;
215 if (propertyType != null && attributeValue != null) {
216 if (String.class.equals(propertyType)) {
217
218 attributeValueObject = attributeValue;
219 }
220 else if (Boolean.class.equals(propertyType) || Boolean.TYPE.equals(propertyType)) {
221 attributeValueObject = Truth.strToBooleanIgnoreCase(attributeValue);
222 } else {
223
224 attributeValueObject = KRADUtils.createObject(propertyType, new Class[]{String.class},
225 new Object[]{attributeValue});
226
227 }
228 }
229 return attributeValueObject;
230 }
231
232 public static Object createObject(Class<?> clazz, Class<?>[] argumentClasses, Object[] argumentValues) {
233 if (clazz == null) {
234 return null;
235 }
236 if (argumentClasses.length == 1 && argumentClasses[0] == String.class) {
237 if (argumentValues.length == 1 && argumentValues[0] != null) {
238 if (clazz == String.class) {
239
240
241 return argumentValues[0];
242 } else {
243
244 Method valueOfMethod = null;
245 try {
246 valueOfMethod = clazz.getMethod("valueOf", String.class);
247 } catch (NoSuchMethodException e) {
248
249 }
250 if (valueOfMethod != null) {
251 try {
252 return valueOfMethod.invoke(null, argumentValues[0]);
253 } catch (Exception e) {
254
255 }
256 }
257 }
258 }
259 }
260 try {
261 Constructor<?> constructor = clazz.getConstructor(argumentClasses);
262 return constructor.newInstance(argumentValues);
263 } catch (Exception e) {
264
265 }
266 return null;
267 }
268
269
270
271
272
273
274
275
276
277
278
279 public static String joinWithQuotes(List<String> list) {
280 if (list == null || list.size() == 0) {
281 return "";
282 }
283
284 return KRADConstants.SINGLE_QUOTE +
285 StringUtils.join(list.iterator(), KRADConstants.SINGLE_QUOTE + "," + KRADConstants.SINGLE_QUOTE) +
286 KRADConstants.SINGLE_QUOTE;
287 }
288
289
290
291
292
293
294
295
296
297 public static String getNamespaceCode(Class<? extends Object> clazz) {
298 ModuleService moduleService = getKualiModuleService().getResponsibleModuleService(clazz);
299 if (moduleService == null) {
300 return KRADConstants.DEFAULT_NAMESPACE;
301 }
302 return moduleService.getModuleConfiguration().getNamespaceCode();
303 }
304
305 public static Map<String, String> getNamespaceAndComponentSimpleName(Class<? extends Object> clazz) {
306 Map<String, String> map = new HashMap<String, String>();
307 map.put(KRADConstants.NAMESPACE_CODE, getNamespaceCode(clazz));
308 map.put(KRADConstants.COMPONENT_NAME, getComponentSimpleName(clazz));
309 return map;
310 }
311
312 public static Map<String, String> getNamespaceAndComponentFullName(Class<? extends Object> clazz) {
313 Map<String, String> map = new HashMap<String, String>();
314 map.put(KRADConstants.NAMESPACE_CODE, getNamespaceCode(clazz));
315 map.put(KRADConstants.COMPONENT_NAME, getComponentFullName(clazz));
316 return map;
317 }
318
319 public static Map<String, String> getNamespaceAndActionClass(Class<? extends Object> clazz) {
320 Map<String, String> map = new HashMap<String, String>();
321 map.put(KRADConstants.NAMESPACE_CODE, getNamespaceCode(clazz));
322 map.put(KRADConstants.ACTION_CLASS, clazz.getName());
323 return map;
324 }
325
326 private static String getComponentSimpleName(Class<? extends Object> clazz) {
327 return clazz.getSimpleName();
328 }
329
330 private static String getComponentFullName(Class<? extends Object> clazz) {
331 return clazz.getName();
332 }
333
334
335
336
337
338
339
340
341 public static Map<String, String> convertStringParameterToMap(String parameter) {
342 Map<String, String> map = new HashMap<String, String>();
343
344 if (StringUtils.isNotBlank(parameter)) {
345 if (StringUtils.contains(parameter, ",")) {
346 String[] fieldConversions = StringUtils.split(parameter, ",");
347
348 for (int i = 0; i < fieldConversions.length; i++) {
349 String fieldConversionStr = fieldConversions[i];
350 if (StringUtils.isNotBlank(fieldConversionStr)) {
351 if (StringUtils.contains(fieldConversionStr, ":")) {
352 String[] fieldConversion = StringUtils.split(fieldConversionStr, ":");
353 map.put(fieldConversion[0], fieldConversion[1]);
354 } else {
355 map.put(fieldConversionStr, fieldConversionStr);
356 }
357 }
358 }
359 } else if (StringUtils.contains(parameter, ":")) {
360 String[] fieldConversion = StringUtils.split(parameter, ":");
361 map.put(fieldConversion[0], fieldConversion[1]);
362 } else {
363 map.put(parameter, parameter);
364 }
365 }
366
367 return map;
368 }
369
370
371
372
373
374
375
376 public static List<String> convertStringParameterToList(String parameter) {
377 List<String> list = new ArrayList<String>();
378
379 if (StringUtils.isNotBlank(parameter)) {
380 if (StringUtils.contains(parameter, ",")) {
381 String[] parameters = StringUtils.split(parameter, ",");
382 List arraysList = Arrays.asList(parameters);
383 list.addAll(arraysList);
384 } else {
385 list.add(parameter);
386 }
387 }
388
389 return list;
390 }
391
392
393
394
395
396
397
398
399 public static String translateToMapSafeKey(String key) {
400 String safeKey = key;
401
402 safeKey = StringUtils.replace(safeKey, "[", "_");
403 safeKey = StringUtils.replace(safeKey, "]", "_");
404
405 return safeKey;
406 }
407
408
409
410
411
412
413
414
415 public static String buildMapParameterString(Map<String, String> map) {
416 String parameterString = "";
417
418 for (Map.Entry<String, String> entry : map.entrySet()) {
419 if (StringUtils.isNotBlank(parameterString)) {
420 parameterString += ",";
421 }
422
423 parameterString += entry.getKey() + ":" + entry.getValue();
424 }
425
426 return parameterString;
427 }
428
429
430
431
432
433
434
435
436
437 public static Map<String, String> getMapFromParameterString(String parameterString) {
438 Map<String, String> map = new HashMap<String, String>();
439
440 String[] entries = parameterString.split(",");
441 for (int i = 0; i < entries.length; i++) {
442 String[] keyValue = entries[i].split(":");
443 if (keyValue.length != 2) {
444 throw new RuntimeException("malformed field conversion pair: " + Arrays.toString(keyValue));
445 }
446
447 map.put(keyValue[0], keyValue[1]);
448 }
449
450 return map;
451 }
452
453
454
455
456
457
458
459
460
461 public static Boolean getRequestParameterAsBoolean(ServletRequest request, String parameterName) {
462 Boolean parameterValue = null;
463
464 String parameterValueStr = request.getParameter(parameterName);
465 if (StringUtils.isNotBlank(parameterValueStr)) {
466 parameterValue = (Boolean) new BooleanFormatter().convertFromPresentationFormat(parameterValueStr);
467 }
468
469 return parameterValue;
470 }
471
472
473
474
475
476
477
478
479
480
481 public static Map<String, String> translateRequestParameterMap(Map<String, String[]> requestParameters) {
482 Map<String, String> parameters = new HashMap<String, String>();
483
484 for (Map.Entry<String, String[]> parameter : requestParameters.entrySet()) {
485 String parameterValue = "";
486 if (parameter.getValue().length > 1) {
487 parameterValue = StringUtils.join(parameter.getValue(), "|");
488 } else {
489 parameterValue = parameter.getValue()[0];
490 }
491 parameters.put(parameter.getKey(), parameterValue);
492 }
493
494 return parameters;
495 }
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511 public static Map<String, String> getParametersFromRequest(List<String> parameterNames, Class<?> parentObjectClass,
512 Map<String, String> requestParameters) {
513 Map<String, String> parameterValues = new HashMap<String, String>();
514
515 for (Iterator<String> iter = parameterNames.iterator(); iter.hasNext(); ) {
516 String keyPropertyName = iter.next();
517
518 if (requestParameters.get(keyPropertyName) != null) {
519 String keyValue = requestParameters.get(keyPropertyName);
520
521
522 if (KRADServiceLocatorWeb.getDataObjectAuthorizationService()
523 .attributeValueNeedsToBeEncryptedOnFormsAndLinks(parentObjectClass, keyPropertyName)) {
524 try {
525 keyValue = StringUtils.removeEnd(keyValue, EncryptionService.ENCRYPTION_POST_PREFIX);
526 keyValue = CoreApiServiceLocator.getEncryptionService().decrypt(keyValue);
527 } catch (GeneralSecurityException e) {
528 throw new RuntimeException(e);
529 }
530 }
531
532 parameterValues.put(keyPropertyName, keyValue);
533 }
534 }
535
536 return parameterValues;
537 }
538
539
540
541
542
543
544
545
546
547
548
549 public static Map<String, String> getPropertyKeyValuesFromDataObject(List<String> propertyNames,
550 Object dataObject) {
551 return getPropertyKeyValuesFromDataObject(propertyNames, Collections.<String>emptyList(), dataObject);
552 }
553
554
555
556
557
558
559
560
561
562
563
564
565 public static Map<String, String> getPropertyKeyValuesFromDataObject(List<String> propertyNames,
566 List<String> securePropertyNames, Object dataObject) {
567 Map<String, String> propertyKeyValues = new HashMap<String, String>();
568
569 if (dataObject == null) {
570 return propertyKeyValues;
571 }
572
573
574 for (String propertyName : propertyNames) {
575 String propertyValue = ObjectPropertyUtils.getPropertyValueAsText(dataObject, propertyName);
576 if (propertyValue == null) {
577 propertyValue = StringUtils.EMPTY;
578 }
579
580
581 if (!isSecure(propertyName, securePropertyNames, dataObject, propertyValue)) {
582 propertyKeyValues.put(propertyName, propertyValue);
583 }
584
585 }
586
587 return propertyKeyValues;
588 }
589
590
591
592
593
594
595
596
597
598
599
600 private static boolean isSecure(String propertyName, List<String> securePropertyNames, Object dataObject,
601 Object propertyValue) {
602 if (propertyValue instanceof String && containsSensitiveDataPatternMatch((String) propertyValue)) {
603 return true;
604 }
605
606 if (containsSecurePropertyName(propertyName, securePropertyNames)) {
607 return true;
608 }
609
610 return KRADServiceLocatorWeb.getDataObjectAuthorizationService()
611 .attributeValueNeedsToBeEncryptedOnFormsAndLinks(dataObject.getClass(), propertyName);
612 }
613
614
615
616
617
618
619
620
621
622 private static boolean containsSecurePropertyName(String propertyName, List<String> securePropertyNames) {
623 if (securePropertyNames == null) {
624 return false;
625 }
626
627 for (String securePropertyName : securePropertyNames) {
628
629 if (Pattern.compile("(?:\\.|^)" + Pattern.quote(securePropertyName) + "(?:\\.|\\[|$)").matcher(propertyName)
630 .find()) {
631 return true;
632 }
633 }
634
635 return false;
636 }
637
638
639
640
641
642
643
644 public static Properties convertMapToProperties(Map<String, String> parameters) {
645 Properties properties = new Properties();
646
647 if (parameters != null) {
648 for (Map.Entry<String, String> parameter : parameters.entrySet()) {
649 properties.put(parameter.getKey(), parameter.getValue());
650 }
651 }
652
653 return properties;
654 }
655
656
657
658
659
660
661
662
663
664
665
666 public static Properties convertRequestMapToProperties(Map<String, String[]> requestParameters) {
667 Properties properties = new Properties();
668
669 if (requestParameters != null) {
670 for (Map.Entry<String, String[]> parameter : requestParameters.entrySet()) {
671 String[] parameterValue = parameter.getValue();
672 String parameterValueString = StringUtils.join(parameterValue, ",");
673
674 properties.put(parameter.getKey(), parameterValueString);
675 }
676 }
677
678 return properties;
679 }
680
681
682
683
684
685
686
687
688
689
690 public static Map<String, Object> coerceRequestParameterTypes(Class<?> dataObjectClass,
691 Map<String, String> parameters) {
692 Map<String, Object> filteredFieldValues = new HashMap<String, Object>();
693 List<java.lang.reflect.Field> allFields = ObjectPropertyUtils.getAllFields(
694 new ArrayList<java.lang.reflect.Field>(), dataObjectClass, Object.class);
695
696 for (String fieldName : parameters.keySet()) {
697 Class<?> propertyType = ObjectPropertyUtils.getPropertyType(dataObjectClass, fieldName);
698
699 String strValue = parameters.get(fieldName);
700
701 if (TypeUtils.isBooleanClass(propertyType) && isConvertAnnotationPresent(allFields, fieldName)) {
702 filteredFieldValues.put(fieldName, Truth.strToBooleanIgnoreCase(strValue));
703 } else if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType)) {
704 try {
705 filteredFieldValues.put(fieldName, hydrateAttributeValue(propertyType, strValue));
706 } catch (Exception nfe) {
707 GlobalVariables.getMessageMap().putError("parameters[" + fieldName + "]",
708 RiceKeyConstants.ERROR_NUMBER, strValue);
709 throw new RuntimeException("Could not parse property value into Number for " + fieldName);
710 }
711 } else if (TypeUtils.isTemporalClass(propertyType)) {
712 try {
713 filteredFieldValues.put(fieldName, CoreApiServiceLocator.getDateTimeService().convertToSqlDate(
714 strValue));
715 } catch (ParseException pe) {
716 GlobalVariables.getMessageMap().putError("parameters[" + fieldName + "]",
717 RiceKeyConstants.ERROR_DATE_TIME, strValue);
718 throw new RuntimeException("Could not parse property value into java.sql.Date for " + fieldName);
719 }
720 }
721
722
723 if (filteredFieldValues.get(fieldName) == null) {
724 filteredFieldValues.put(fieldName, parameters.get(fieldName));
725 }
726
727 }
728 return filteredFieldValues;
729
730 }
731
732
733
734
735
736
737
738
739 private static boolean isConvertAnnotationPresent(List<java.lang.reflect.Field> allFields, String fieldName) {
740
741 boolean convertAnnotationFound = false;
742 for (java.lang.reflect.Field f : allFields) {
743 if (f.getName().equalsIgnoreCase(fieldName)) {
744 if (f.getAnnotation(javax.persistence.Convert.class) != null) {
745 convertAnnotationFound = true;
746 }
747 break;
748 }
749 }
750
751 return convertAnnotationFound;
752 }
753
754
755
756
757
758
759
760
761
762
763
764
765 public static boolean containsSensitiveDataPatternMatch(String fieldValue) {
766 if (StringUtils.isBlank(fieldValue)) {
767 return false;
768 }
769
770 ParameterService parameterService = CoreFrameworkServiceLocator.getParameterService();
771 Collection<String> sensitiveDataPatterns = parameterService.getParameterValuesAsString(
772 KRADConstants.KNS_NAMESPACE, ParameterConstants.ALL_COMPONENT,
773 KRADConstants.SystemGroupParameterNames.SENSITIVE_DATA_PATTERNS);
774
775 for (String pattern : sensitiveDataPatterns) {
776 if (Pattern.compile(pattern).matcher(fieldValue).find()) {
777 return true;
778 }
779 }
780
781 return false;
782 }
783
784
785
786
787
788
789
790 public static String[] stripXSSPatterns(String[] values) {
791 ArrayList<String> strippedValues = new ArrayList<String>();
792
793 for (String value : values) {
794 strippedValues.add(stripXSSPatterns(value));
795 }
796
797 return strippedValues.toArray(new String[]{});
798 }
799
800
801
802
803
804
805
806 public static String stripXSSPatterns(String value) {
807 if (value == null) {
808 return null;
809 }
810
811
812 value = value.replaceAll("", "");
813
814
815 Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
816 value = scriptPattern.matcher(value).replaceAll("");
817
818
819 scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",
820 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
821 value = scriptPattern.matcher(value).replaceAll("");
822
823 scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",
824 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
825 value = scriptPattern.matcher(value).replaceAll("");
826
827
828 scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
829 value = scriptPattern.matcher(value).replaceAll("");
830
831
832 scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
833 value = scriptPattern.matcher(value).replaceAll("");
834
835
836 scriptPattern = Pattern.compile("eval\\((.*?)\\)",
837 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
838 value = scriptPattern.matcher(value).replaceAll("");
839
840
841 scriptPattern = Pattern.compile("expression\\((.*?)\\)",
842 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
843 value = scriptPattern.matcher(value).replaceAll("");
844
845
846 scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
847 value = scriptPattern.matcher(value).replaceAll("");
848
849
850 scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
851 value = scriptPattern.matcher(value).replaceAll("");
852
853
854 scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
855 value = scriptPattern.matcher(value).replaceAll("");
856
857 return value;
858 }
859
860
861
862
863
864
865
866
867
868
869
870
871
872 public static final UserSession getUserSessionFromRequest(HttpServletRequest request) {
873 return (UserSession) request.getSession().getAttribute(KRADConstants.USER_SESSION_KEY);
874 }
875
876
877
878
879
880
881 public static boolean isProductionEnvironment() {
882 return CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
883 KRADConstants.PROD_ENVIRONMENT_CODE_KEY).equalsIgnoreCase(
884 CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
885 KRADConstants.ENVIRONMENT_KEY));
886 }
887
888
889
890
891
892
893
894
895
896
897 public static String getMessageText(ErrorMessage errorMessage, boolean processPrefixSuffix) {
898 String message = "";
899 if (errorMessage != null && errorMessage.getErrorKey() != null) {
900 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
901
902
903 message = messageService.getMessageText(errorMessage.getNamespaceCode(), errorMessage.getComponentCode(),
904 errorMessage.getErrorKey());
905 if (message == null) {
906 message = "Intended message with key: " + errorMessage.getErrorKey() + " not found.";
907 }
908
909 if (errorMessage.getMessageParameters() != null && StringUtils.isNotBlank(message)) {
910 message = message.replace("'", "''");
911 message = MessageFormat.format(message, (Object[]) errorMessage.getMessageParameters());
912 }
913
914
915 if (StringUtils.isNotBlank(errorMessage.getMessagePrefixKey()) && processPrefixSuffix) {
916 String prefix = messageService.getMessageText(errorMessage.getNamespaceCode(),
917 errorMessage.getComponentCode(), errorMessage.getMessagePrefixKey());
918
919 if (errorMessage.getMessagePrefixParameters() != null && StringUtils.isNotBlank(prefix)) {
920 prefix = prefix.replace("'", "''");
921 prefix = MessageFormat.format(prefix, (Object[]) errorMessage.getMessagePrefixParameters());
922 }
923
924 if (StringUtils.isNotBlank(prefix)) {
925 message = prefix + " " + message;
926 }
927 }
928
929
930 if (StringUtils.isNotBlank(errorMessage.getMessageSuffixKey()) && processPrefixSuffix) {
931 String suffix = messageService.getMessageText(errorMessage.getNamespaceCode(),
932 errorMessage.getComponentCode(), errorMessage.getMessageSuffixKey());
933
934 if (errorMessage.getMessageSuffixParameters() != null && StringUtils.isNotBlank(suffix)) {
935 suffix = suffix.replace("'", "''");
936 suffix = MessageFormat.format(suffix, (Object[]) errorMessage.getMessageSuffixParameters());
937 }
938
939 if (StringUtils.isNotBlank(suffix)) {
940 message = message + " " + suffix;
941 }
942 }
943 }
944
945 return message;
946 }
947
948
949
950
951 public static void logErrors() {
952 if (!GlobalVariables.getMessageMap().hasErrors()) {
953 return;
954 }
955
956 for (Iterator<Map.Entry<String, List<ErrorMessage>>> i =
957 GlobalVariables.getMessageMap().getAllPropertiesAndErrors().iterator(); i.hasNext(); ) {
958 Map.Entry<String, List<ErrorMessage>> e = i.next();
959
960 StringBuffer logMessage = buildMessage(e);
961 LOG.error(logMessage);
962 }
963 }
964
965
966
967
968
969
970
971
972 private static StringBuffer buildMessage(Map.Entry<String, List<ErrorMessage>> e) {
973 StringBuffer logMessage = new StringBuffer();
974 logMessage.append("[" + e.getKey() + "] ");
975 boolean first = true;
976
977 List<ErrorMessage> errorList = e.getValue();
978 for (Iterator<ErrorMessage> j = errorList.iterator(); j.hasNext(); ) {
979 ErrorMessage em = j.next();
980
981
982 if (first) {
983 first = false;
984 } else {
985 logMessage.append(";");
986 }
987 logMessage.append(em);
988 }
989 return logMessage;
990 }
991
992
993
994
995
996
997
998
999 public static String getRequestStringFromMap(Map<String, String> requestParameters) {
1000 String requestString = "";
1001
1002 if (requestParameters.isEmpty()) {
1003 return requestString;
1004 }
1005
1006 URLCodec urlCodec = new URLCodec(KRADConstants.DEFAULT_ENCODING);
1007
1008 for (String key : requestParameters.keySet()) {
1009 String value = null;
1010 try {
1011 value = urlCodec.encode(requestParameters.get(key));
1012 } catch (EncoderException e) {
1013 throw new RuntimeException("Unable to encode parameter name or value: " + key + "=" + value, e);
1014 }
1015
1016 if (StringUtils.isNotBlank(requestString)) {
1017 requestString = requestString + "&";
1018 }
1019
1020 requestString = requestString + key + "=" + value;
1021 }
1022
1023 return "?" + requestString;
1024 }
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036 public static void addAttachmentToResponse(HttpServletResponse response, InputStream inputStream,
1037 String contentType, String fileName, long fileSize) throws IOException {
1038
1039
1040
1041 String updateFileName;
1042 if (fileName.contains("\"")) {
1043 updateFileName = fileName.replaceAll("\"", "");
1044 } else {
1045 updateFileName = fileName;
1046 }
1047
1048
1049 response.setContentType(contentType);
1050 response.setContentLength(org.springframework.util.NumberUtils.convertNumberToTargetClass(fileSize,
1051 Integer.class));
1052 response.setHeader("Content-disposition", "attachment; filename=\"" + updateFileName + "\"");
1053 response.setHeader("Expires", "0");
1054 response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
1055 response.setHeader("Pragma", "public");
1056
1057
1058 FileCopyUtils.copy(inputStream, response.getOutputStream());
1059 }
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070 public static String buildViewUrl(String baseUrl, String controllerMapping, String viewId) {
1071 Assert.hasLength(baseUrl, "base url is null or empty");
1072 Assert.hasLength(controllerMapping, "controller mapping is null or empty");
1073 Assert.hasLength(viewId, "view id is null or empty");
1074
1075 StringBuffer url = new StringBuffer();
1076
1077 url.append(baseUrl);
1078
1079 if (!baseUrl.endsWith("/")) {
1080 url.append("/");
1081 }
1082
1083 url.append(controllerMapping);
1084
1085 url.append("?");
1086 url.append(UifParameters.VIEW_ID);
1087 url.append("=");
1088 url.append(viewId);
1089
1090 return url.toString();
1091 }
1092
1093
1094
1095
1096
1097
1098
1099 public static void cleanRequestParameters(Properties requestParameters) {
1100 requestParameters.remove(UifParameters.SESSION_ID);
1101 requestParameters.remove(UifParameters.AJAX_REQUEST);
1102 requestParameters.remove(UifParameters.AJAX_RETURN_TYPE);
1103 requestParameters.remove(UifParameters.FORM_KEY);
1104 requestParameters.remove(UifParameters.JUMP_TO_ID);
1105 requestParameters.remove(UifParameters.FOCUS_ID);
1106 }
1107
1108
1109
1110
1111
1112
1113
1114 public static String getFullURL(HttpServletRequest request) {
1115 if (request == null) {
1116 return null;
1117 }
1118
1119 StringBuffer requestURL = request.getRequestURL();
1120 String queryString = request.getQueryString();
1121
1122 if (queryString == null) {
1123 return requestURL.toString();
1124 } else {
1125 return requestURL.append('?').append(queryString).toString();
1126 }
1127 }
1128
1129
1130
1131
1132
1133
1134
1135
1136 public static boolean areDifferentDomains(String firstDomain, String secondDomain) {
1137 try {
1138 URL urlOne = new URL(firstDomain.toLowerCase());
1139 URL urlTwo = new URL(secondDomain.toLowerCase());
1140
1141 if (urlOne.getHost().equals(urlTwo.getHost())) {
1142 LOG.debug("Hosts "
1143 + urlOne.getHost()
1144 + " of domains "
1145 + firstDomain
1146 + " and "
1147 + secondDomain
1148 + " were determined to be equal");
1149
1150 return false;
1151 } else {
1152 LOG.debug("Hosts "
1153 + urlOne.getHost()
1154 + " of domains "
1155 + firstDomain
1156 + " and "
1157 + secondDomain
1158 + " are not equal");
1159
1160 return true;
1161 }
1162 } catch (MalformedURLException mue) {
1163 LOG.error("Unable to successfully compare domains " + firstDomain + " and " + secondDomain);
1164 }
1165
1166 return true;
1167 }
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179 public static String generateUniqueViewTitle(UifFormBase form, View view) {
1180 String title = view.getHeader().getHeaderText();
1181
1182 String viewLabelPropertyName = "";
1183
1184 Class<?> dataObjectClass;
1185 if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
1186 dataObjectClass = ObjectPropertyUtils.getPropertyType(form, view.getDefaultBindingObjectPath());
1187 } else {
1188 dataObjectClass = view.getFormClass();
1189 }
1190
1191 if (dataObjectClass != null) {
1192 viewLabelPropertyName = KRADServiceLocatorWeb.getLegacyDataAdapter().getTitleAttribute(dataObjectClass);
1193 }
1194
1195 String viewLabelPropertyPath = "";
1196 if (StringUtils.isNotBlank(viewLabelPropertyName)) {
1197
1198 if (!viewLabelPropertyName.startsWith(UifConstants.NO_BIND_ADJUST_PREFIX)) {
1199 if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
1200 viewLabelPropertyPath = view.getDefaultBindingObjectPath() + "." + viewLabelPropertyName;
1201 }
1202 } else {
1203 viewLabelPropertyPath = StringUtils.removeStart(viewLabelPropertyName,
1204 UifConstants.NO_BIND_ADJUST_PREFIX);
1205 }
1206 } else {
1207
1208 if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
1209 dataObjectClass = ViewModelUtils.getObjectClassForMetadata(view, form,
1210 view.getDefaultBindingObjectPath());
1211 } else {
1212 dataObjectClass = view.getFormClass();
1213 }
1214
1215 if (dataObjectClass != null) {
1216 String titleAttribute = KRADServiceLocatorWeb.getLegacyDataAdapter().getTitleAttribute(dataObjectClass);
1217 if (StringUtils.isNotBlank(titleAttribute)) {
1218 viewLabelPropertyPath = view.getDefaultBindingObjectPath() + "." + titleAttribute;
1219 }
1220 }
1221 }
1222
1223 Object viewLabelPropertyValue = null;
1224 if (StringUtils.isNotBlank(viewLabelPropertyPath) && ObjectPropertyUtils.isReadableProperty(form,
1225 viewLabelPropertyPath)) {
1226 viewLabelPropertyValue = ObjectPropertyUtils.getPropertyValueAsText(form, viewLabelPropertyPath);
1227 }
1228
1229 if (viewLabelPropertyValue != null && StringUtils.isNotBlank(viewLabelPropertyValue.toString()) && StringUtils
1230 .isNotBlank(title)) {
1231 return title + " (" + viewLabelPropertyValue.toString() + ")";
1232 } else {
1233 return title;
1234 }
1235 }
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250 public static String buildAttributeTitleString(String prependText, Class<?> element,
1251 Map<String, String> keyValueMap) {
1252 StringBuffer titleText = new StringBuffer(prependText);
1253
1254 for (String key : keyValueMap.keySet()) {
1255 String fieldVal = keyValueMap.get(key).toString();
1256
1257 titleText.append(" "
1258 + KRADServiceLocatorWeb.getDataDictionaryService().getAttributeLabel(element, key)
1259 + "="
1260 + fieldVal.toString());
1261 }
1262
1263 return titleText.toString();
1264 }
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277 public static String getSimpleFieldValue(Object model, Field field) {
1278 if (field == null) {
1279 return null;
1280 }
1281
1282 String value = null;
1283
1284 if (field instanceof DataField) {
1285 String propertyPath = ((DataField) field).getBindingInfo().getBindingPath();
1286 Object valueObject = null;
1287
1288 if (field.isHidden()) {
1289 return "";
1290 }
1291
1292
1293 if (ObjectPropertyUtils.isReadableProperty(model, propertyPath)) {
1294 valueObject = ObjectPropertyUtils.getPropertyValueAsText(model, propertyPath);
1295 }
1296
1297
1298 if (valueObject != null && !((DataField) field).isApplyMask()) {
1299 value = valueObject.toString();
1300 } else if (valueObject != null && ((DataField) field).isApplyMask()) {
1301 value = ((DataField) field).getMaskFormatter().maskValue(valueObject);
1302 }
1303 } else if (field instanceof ActionField) {
1304 value = ((ActionField) field).getActionLabel();
1305
1306
1307 if (StringUtils.isBlank(value) && ((ActionField) field).getActionImage() != null) {
1308 value = ((ActionField) field).getActionImage().getAltText();
1309 }
1310 } else if (field instanceof LinkField) {
1311 value = ((LinkField) field).getLinkText();
1312 } else if (field instanceof ImageField) {
1313 value = ((ImageField) field).getAltText();
1314 } else if (field instanceof MessageField && ((MessageField) field).getMessage() != null) {
1315 value = ((MessageField) field).getMessage().getMessageText();
1316 } else if (field instanceof SpaceField) {
1317 value = "";
1318 } else if (field instanceof FieldGroup
1319 && ((FieldGroup) field).getGroup() != null
1320 && ((FieldGroup) field).getGroup().getItems() != null
1321 && !((FieldGroup) field).getGroup().getItems().isEmpty()) {
1322
1323 Component firstComponent = ((FieldGroup) field).getGroup().getItems().get(0);
1324
1325
1326 if (firstComponent != null && firstComponent instanceof Field) {
1327 value = getSimpleFieldValue(model, (Field) firstComponent);
1328 } else if (firstComponent instanceof Action && StringUtils.isNotBlank(
1329 ((Action) firstComponent).getActionLabel())) {
1330 value = ((Action) firstComponent).getActionLabel();
1331 } else if (firstComponent instanceof Action && ((Action) firstComponent).getActionImage() != null) {
1332 value = ((Action) firstComponent).getActionImage().getAltText();
1333 } else if (firstComponent instanceof Link) {
1334 value = ((Link) firstComponent).getLinkText();
1335 } else if (firstComponent instanceof Image) {
1336 value = ((Image) firstComponent).getAltText();
1337 } else if (firstComponent instanceof org.kuali.rice.krad.uif.element.Message) {
1338 value = ((org.kuali.rice.krad.uif.element.Message) firstComponent).getMessageText();
1339 } else {
1340 value = null;
1341 }
1342 }
1343
1344 return value;
1345 }
1346
1347
1348
1349
1350
1351
1352
1353 public static String convertToHTMLAttributeSafeString(String message) {
1354 if (StringUtils.isBlank(message)) {
1355 return message;
1356 }
1357
1358 if (message.contains("\"")) {
1359 message = message.replace("\"", """);
1360 }
1361 if (message.contains("'")) {
1362 message = message.replace("'", "'");
1363 }
1364 if (message.contains("\\")) {
1365 message = message.replace("\\", "\");
1366 }
1367
1368 return message;
1369 }
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382 public static String generateRowCssClassString(Map<String, String> conditionalRowCssClasses, int lineIndex,
1383 boolean isOdd, Map<String, Object> lineContext, ExpressionEvaluator expressionEvaluator) {
1384 String rowCss = "";
1385 if (conditionalRowCssClasses == null || conditionalRowCssClasses.isEmpty()) {
1386 return rowCss;
1387 }
1388
1389 for (String cssRule : conditionalRowCssClasses.keySet()) {
1390 if (cssRule.startsWith(UifConstants.EL_PLACEHOLDER_PREFIX) && lineContext != null &&
1391 expressionEvaluator != null) {
1392 String outcome = expressionEvaluator.evaluateExpressionTemplate(lineContext, cssRule);
1393 if (outcome != null && Boolean.parseBoolean(outcome)) {
1394 rowCss = rowCss + " " + conditionalRowCssClasses.get(cssRule);
1395 }
1396 } else if (cssRule.equals(UifConstants.RowSelection.ALL)) {
1397 rowCss = rowCss + " " + conditionalRowCssClasses.get(cssRule);
1398 } else if (cssRule.equals(UifConstants.RowSelection.EVEN) && !isOdd) {
1399 rowCss = rowCss + " " + conditionalRowCssClasses.get(cssRule);
1400 } else if (cssRule.equals(UifConstants.RowSelection.ODD) && isOdd) {
1401 rowCss = rowCss + " " + conditionalRowCssClasses.get(cssRule);
1402 } else if (StringUtils.isNumeric(cssRule) && (lineIndex + 1) == Integer.parseInt(cssRule)) {
1403 rowCss = rowCss + " " + conditionalRowCssClasses.get(cssRule);
1404 }
1405 }
1406
1407 rowCss = StringUtils.removeStart(rowCss, " ");
1408
1409 return rowCss;
1410 }
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424 static public Class easyGetPropertyType(Object object,
1425 String propertyName) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
1426 if (LegacyUtils.useLegacyForObject(object)) {
1427 return PropertyUtils.getPropertyType(object, propertyName);
1428 }
1429 return KradDataServiceLocator.getDataObjectService().wrap(object).getPropertyType(propertyName);
1430 }
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443 public static void setObjectProperty(Object bo, String propertyName,
1444 Object propertyValue) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
1445 Class propertyType = easyGetPropertyType(bo, propertyName);
1446 setObjectProperty(bo, propertyName, propertyType, propertyValue);
1447
1448 }
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462 public static void setObjectProperty(Object bo, String propertyName, Class propertyType,
1463 Object propertyValue) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
1464 KRADServiceLocatorWeb.getLegacyDataAdapter().setObjectProperty(bo, propertyName, propertyType, propertyValue);
1465 }
1466
1467
1468
1469
1470
1471
1472
1473 public static String clean(String string) {
1474 for (SearchOperator op : SearchOperator.QUERY_CHARACTERS) {
1475 string = StringUtils.replace(string, op.op(), KRADConstants.EMPTY_STRING);
1476 }
1477 return string;
1478 }
1479
1480
1481
1482
1483
1484
1485
1486 public static boolean isNull(Object object) {
1487 if (object == null) {
1488 return true;
1489 }
1490 return KRADServiceLocatorWeb.getLegacyDataAdapter().isNull(object);
1491 }
1492
1493
1494
1495
1496
1497
1498
1499 public static boolean isNotNull(Object object) {
1500 return !isNull(object);
1501 }
1502
1503
1504
1505
1506
1507
1508
1509 public static Class materializeClassForProxiedObject(Object object) {
1510 return KRADServiceLocatorWeb.getLegacyDataAdapter().materializeClassForProxiedObject(object);
1511 }
1512
1513
1514
1515
1516
1517
1518
1519
1520 public static void materializeObjects(Collection possiblyProxiedObjects) {
1521 for (Iterator i = possiblyProxiedObjects.iterator(); i.hasNext(); ) {
1522 KRADUtils.isNotNull(i.next());
1523 }
1524 }
1525
1526
1527
1528
1529
1530
1531
1532 public static String getNestedAttributePrefix(String attributeName) {
1533 int lastIndex = PropertyAccessorUtils.getLastNestedPropertySeparatorIndex(attributeName);
1534
1535 return lastIndex != -1 ? StringUtils.substring(attributeName, 0, lastIndex) : StringUtils.EMPTY;
1536 }
1537
1538
1539
1540
1541
1542
1543
1544 public static String getNestedAttributePrimitive(String attributeName) {
1545 int lastIndex = PropertyAccessorUtils.getLastNestedPropertySeparatorIndex(attributeName);
1546
1547 return lastIndex != -1 ? StringUtils.substring(attributeName, lastIndex + 1) : attributeName;
1548 }
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563 public static Object getNestedValue(Object bo, String fieldName) {
1564 return KRADServiceLocatorWeb.getLegacyDataAdapter().getNestedValue(bo, fieldName);
1565 }
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578 public static <T> T createNewObjectFromClass(Class<T> clazz) {
1579 if (clazz == null) {
1580 throw new RuntimeException("BO class was passed in as null");
1581 }
1582 return (T) KRADServiceLocatorWeb.getLegacyDataAdapter().createNewObjectFromClass(clazz);
1583 }
1584
1585 private static KualiModuleService getKualiModuleService() {
1586 if (kualiModuleService == null) {
1587 kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
1588 }
1589 return kualiModuleService;
1590 }
1591
1592
1593
1594
1595
1596
1597
1598
1599 public static void syncClientSideStateForComponent(Component component, Map<String, Object> clientSideState) {
1600
1601 Map<String, Object> componentState = null;
1602 if (component instanceof View) {
1603 componentState = clientSideState;
1604 } else {
1605 if (clientSideState.containsKey(component.getId())) {
1606 componentState = (Map<String, Object>) clientSideState.get(component.getId());
1607 }
1608 }
1609
1610
1611 if ((componentState != null) && (!componentState.isEmpty())) {
1612 Map<String, Annotation> annotatedFields = CopyUtils.getFieldsWithAnnotation(component.getClass(),
1613 ClientSideState.class);
1614
1615 for (Map.Entry<String, Annotation> annotatedField : annotatedFields.entrySet()) {
1616 ClientSideState clientSideStateAnnot = (ClientSideState) annotatedField.getValue();
1617
1618 String variableName = clientSideStateAnnot.variableName();
1619 if (StringUtils.isBlank(variableName)) {
1620 variableName = annotatedField.getKey();
1621 }
1622
1623 if (componentState.containsKey(variableName)) {
1624 Object value = componentState.get(variableName);
1625 ObjectPropertyUtils.setPropertyValue(component, annotatedField.getKey(), value);
1626 }
1627 }
1628 }
1629 }
1630
1631 }