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 = fieldConversionStr.split(":",-1);
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 = parameter.split(":",-1);
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 boolean isSecure = isSecure(keyPropertyName, parentObjectClass);
523
524 if (StringUtils.endsWith(keyValue, EncryptionService.ENCRYPTION_POST_PREFIX)) {
525 keyValue = StringUtils.removeEnd(keyValue, EncryptionService.ENCRYPTION_POST_PREFIX);
526 isSecure = true;
527 }
528
529
530 if (isSecure) {
531 try {
532 if (CoreApiServiceLocator.getEncryptionService().isEnabled()) {
533 keyValue = CoreApiServiceLocator.getEncryptionService().decrypt(keyValue);
534 }
535 } catch (GeneralSecurityException e) {
536 String message = "Data object class " + parentObjectClass + " property " + keyPropertyName
537 + " should have been encrypted, but there was a problem decrypting it.";
538 LOG.error(message);
539
540 throw new RuntimeException(message, e);
541 }
542 }
543
544 parameterValues.put(keyPropertyName, keyValue);
545 }
546 }
547
548 return parameterValues;
549 }
550
551
552
553
554
555
556
557
558
559
560
561 public static Map<String, String> getPropertyKeyValuesFromDataObject(List<String> propertyNames, Object dataObject) {
562 return getPropertyKeyValuesFromDataObject(propertyNames, Collections.<String>emptyList(), dataObject);
563 }
564
565
566
567
568
569
570
571
572
573
574
575
576 public static Map<String, String> getPropertyKeyValuesFromDataObject(List<String> propertyNames,
577 List<String> securePropertyNames, Object dataObject) {
578 Map<String, String> propertyKeyValues = new HashMap<String, String>();
579
580 if (dataObject == null) {
581 return propertyKeyValues;
582 }
583
584
585 for (String propertyName : propertyNames) {
586 String propertyValue = ObjectPropertyUtils.getPropertyValueAsText(dataObject, propertyName);
587
588 if (propertyValue == null) {
589 propertyValue = StringUtils.EMPTY;
590 }
591
592
593 if (!isSecure(propertyName, securePropertyNames, dataObject.getClass())) {
594 propertyKeyValues.put(propertyName, propertyValue);
595 }
596 }
597
598 return propertyKeyValues;
599 }
600
601
602
603
604
605
606
607
608
609
610 public static boolean isSecure(String propertyName, Class<?> dataObjectClass) {
611 return isSecure(propertyName, Collections.<String>emptyList(), dataObjectClass);
612 }
613
614
615
616
617
618
619
620
621
622
623
624 public static boolean isSecure(String propertyName, List<String> securePropertyNames, Class<?> dataObjectClass) {
625 if (containsSecurePropertyName(propertyName, securePropertyNames)) {
626 return true;
627 }
628
629 return KRADServiceLocatorWeb.getDataObjectAuthorizationService()
630 .attributeValueNeedsToBeEncryptedOnFormsAndLinks(dataObjectClass, propertyName);
631 }
632
633
634
635
636
637
638
639
640
641 private static boolean containsSecurePropertyName(String propertyName, List<String> securePropertyNames) {
642 if (securePropertyNames == null) {
643 return false;
644 }
645
646 for (String securePropertyName : securePropertyNames) {
647
648 if (Pattern.compile("(?:\\.|^)" + Pattern.quote(securePropertyName) + "(?:\\.|\\[|$)").matcher(propertyName)
649 .find()) {
650 return true;
651 }
652 }
653
654 return false;
655 }
656
657
658
659
660
661
662
663 public static Properties convertMapToProperties(Map<String, String> parameters) {
664 Properties properties = new Properties();
665
666 if (parameters != null) {
667 for (Map.Entry<String, String> parameter : parameters.entrySet()) {
668 properties.put(parameter.getKey(), parameter.getValue());
669 }
670 }
671
672 return properties;
673 }
674
675
676
677
678
679
680
681
682
683
684
685 public static Properties convertRequestMapToProperties(Map<String, String[]> requestParameters) {
686 Properties properties = new Properties();
687
688 if (requestParameters != null) {
689 for (Map.Entry<String, String[]> parameter : requestParameters.entrySet()) {
690 String[] parameterValue = parameter.getValue();
691 String parameterValueString = StringUtils.join(parameterValue, ",");
692
693 properties.put(parameter.getKey(), parameterValueString);
694 }
695 }
696
697 return properties;
698 }
699
700
701
702
703
704
705
706
707
708
709 public static Map<String, Object> coerceRequestParameterTypes(Class<?> dataObjectClass,
710 Map<String, String> parameters) {
711 Map<String, Object> filteredFieldValues = new HashMap<String, Object>();
712 List<java.lang.reflect.Field> allFields = ObjectPropertyUtils.getAllFields(
713 new ArrayList<java.lang.reflect.Field>(), dataObjectClass, Object.class);
714
715 for (String fieldName : parameters.keySet()) {
716 Class<?> propertyType = ObjectPropertyUtils.getPropertyType(dataObjectClass, fieldName);
717
718 String strValue = parameters.get(fieldName);
719
720 if (TypeUtils.isBooleanClass(propertyType) && isConvertAnnotationPresent(allFields, fieldName)) {
721 filteredFieldValues.put(fieldName, Truth.strToBooleanIgnoreCase(strValue));
722 } else if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType)) {
723 try {
724 filteredFieldValues.put(fieldName, hydrateAttributeValue(propertyType, strValue));
725 } catch (Exception nfe) {
726 GlobalVariables.getMessageMap().putError("parameters[" + fieldName + "]",
727 RiceKeyConstants.ERROR_NUMBER, strValue);
728 throw new RuntimeException("Could not parse property value into Number for " + fieldName);
729 }
730 } else if (TypeUtils.isTemporalClass(propertyType)) {
731 try {
732 filteredFieldValues.put(fieldName, CoreApiServiceLocator.getDateTimeService().convertToSqlDate(
733 strValue));
734 } catch (ParseException pe) {
735 GlobalVariables.getMessageMap().putError("parameters[" + fieldName + "]",
736 RiceKeyConstants.ERROR_DATE_TIME, strValue);
737 throw new RuntimeException("Could not parse property value into java.sql.Date for " + fieldName);
738 }
739 }
740
741
742 if (filteredFieldValues.get(fieldName) == null) {
743 filteredFieldValues.put(fieldName, parameters.get(fieldName));
744 }
745
746 }
747 return filteredFieldValues;
748
749 }
750
751
752
753
754
755
756
757
758 private static boolean isConvertAnnotationPresent(List<java.lang.reflect.Field> allFields, String fieldName) {
759
760 boolean convertAnnotationFound = false;
761 for (java.lang.reflect.Field f : allFields) {
762 if (f.getName().equalsIgnoreCase(fieldName)) {
763 if (f.getAnnotation(javax.persistence.Convert.class) != null) {
764 convertAnnotationFound = true;
765 }
766 break;
767 }
768 }
769
770 return convertAnnotationFound;
771 }
772
773
774
775
776
777
778
779
780
781
782
783
784 public static boolean containsSensitiveDataPatternMatch(String fieldValue) {
785 if (StringUtils.isBlank(fieldValue)) {
786 return false;
787 }
788
789 ParameterService parameterService = CoreFrameworkServiceLocator.getParameterService();
790 Collection<String> sensitiveDataPatterns = parameterService.getParameterValuesAsString(
791 KRADConstants.KNS_NAMESPACE, ParameterConstants.ALL_COMPONENT,
792 KRADConstants.SystemGroupParameterNames.SENSITIVE_DATA_PATTERNS);
793
794 for (String pattern : sensitiveDataPatterns) {
795 if (Pattern.compile(pattern).matcher(fieldValue).find()) {
796 return true;
797 }
798 }
799
800 return false;
801 }
802
803
804
805
806
807
808
809 public static String[] stripXSSPatterns(String[] values) {
810 ArrayList<String> strippedValues = new ArrayList<String>();
811
812 for (String value : values) {
813 strippedValues.add(stripXSSPatterns(value));
814 }
815
816 return strippedValues.toArray(new String[]{});
817 }
818
819
820
821
822
823
824
825 public static String stripXSSPatterns(String value) {
826 if (value == null) {
827 return null;
828 }
829
830
831 value = value.replaceAll("", "");
832
833
834 Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
835 value = scriptPattern.matcher(value).replaceAll("");
836
837
838 scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",
839 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
840 value = scriptPattern.matcher(value).replaceAll("");
841
842 scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",
843 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
844 value = scriptPattern.matcher(value).replaceAll("");
845
846
847 scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
848 value = scriptPattern.matcher(value).replaceAll("");
849
850
851 scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
852 value = scriptPattern.matcher(value).replaceAll("");
853
854
855 scriptPattern = Pattern.compile("eval\\((.*?)\\)",
856 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
857 value = scriptPattern.matcher(value).replaceAll("");
858
859
860 scriptPattern = Pattern.compile("expression\\((.*?)\\)",
861 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
862 value = scriptPattern.matcher(value).replaceAll("");
863
864
865 scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
866 value = scriptPattern.matcher(value).replaceAll("");
867
868
869 scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
870 value = scriptPattern.matcher(value).replaceAll("");
871
872
873 scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
874 value = scriptPattern.matcher(value).replaceAll("");
875
876 return value;
877 }
878
879
880
881
882
883
884
885
886
887
888
889
890
891 public static final UserSession getUserSessionFromRequest(HttpServletRequest request) {
892 return (UserSession) request.getSession().getAttribute(KRADConstants.USER_SESSION_KEY);
893 }
894
895
896
897
898
899
900 public static boolean isProductionEnvironment() {
901 return CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
902 KRADConstants.PROD_ENVIRONMENT_CODE_KEY).equalsIgnoreCase(
903 CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
904 KRADConstants.ENVIRONMENT_KEY));
905 }
906
907
908
909
910
911
912
913
914
915
916 public static String getMessageText(ErrorMessage errorMessage, boolean processPrefixSuffix) {
917 String message = "";
918 if (errorMessage != null && errorMessage.getErrorKey() != null) {
919 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
920
921
922 message = messageService.getMessageText(errorMessage.getNamespaceCode(), errorMessage.getComponentCode(),
923 errorMessage.getErrorKey());
924 if (message == null) {
925 message = "Intended message with key: " + errorMessage.getErrorKey() + " not found.";
926 }
927
928 if (errorMessage.getMessageParameters() != null && StringUtils.isNotBlank(message)) {
929 message = message.replace("'", "''");
930 message = MessageFormat.format(message, (Object[]) errorMessage.getMessageParameters());
931 }
932
933
934 if (StringUtils.isNotBlank(errorMessage.getMessagePrefixKey()) && processPrefixSuffix) {
935 String prefix = messageService.getMessageText(errorMessage.getNamespaceCode(),
936 errorMessage.getComponentCode(), errorMessage.getMessagePrefixKey());
937
938 if (errorMessage.getMessagePrefixParameters() != null && StringUtils.isNotBlank(prefix)) {
939 prefix = prefix.replace("'", "''");
940 prefix = MessageFormat.format(prefix, (Object[]) errorMessage.getMessagePrefixParameters());
941 }
942
943 if (StringUtils.isNotBlank(prefix)) {
944 message = prefix + " " + message;
945 }
946 }
947
948
949 if (StringUtils.isNotBlank(errorMessage.getMessageSuffixKey()) && processPrefixSuffix) {
950 String suffix = messageService.getMessageText(errorMessage.getNamespaceCode(),
951 errorMessage.getComponentCode(), errorMessage.getMessageSuffixKey());
952
953 if (errorMessage.getMessageSuffixParameters() != null && StringUtils.isNotBlank(suffix)) {
954 suffix = suffix.replace("'", "''");
955 suffix = MessageFormat.format(suffix, (Object[]) errorMessage.getMessageSuffixParameters());
956 }
957
958 if (StringUtils.isNotBlank(suffix)) {
959 message = message + " " + suffix;
960 }
961 }
962 }
963
964 return message;
965 }
966
967
968
969
970 public static void logErrors() {
971 if (!GlobalVariables.getMessageMap().hasErrors()) {
972 return;
973 }
974
975 for (Iterator<Map.Entry<String, List<ErrorMessage>>> i =
976 GlobalVariables.getMessageMap().getAllPropertiesAndErrors().iterator(); i.hasNext(); ) {
977 Map.Entry<String, List<ErrorMessage>> e = i.next();
978
979 StringBuffer logMessage = buildMessage(e);
980 LOG.error(logMessage);
981 }
982 }
983
984
985
986
987
988
989
990
991 private static StringBuffer buildMessage(Map.Entry<String, List<ErrorMessage>> e) {
992 StringBuffer logMessage = new StringBuffer();
993 logMessage.append("[" + e.getKey() + "] ");
994 boolean first = true;
995
996 List<ErrorMessage> errorList = e.getValue();
997 for (Iterator<ErrorMessage> j = errorList.iterator(); j.hasNext(); ) {
998 ErrorMessage em = j.next();
999
1000
1001 if (first) {
1002 first = false;
1003 } else {
1004 logMessage.append(";");
1005 }
1006 logMessage.append(em);
1007 }
1008 return logMessage;
1009 }
1010
1011
1012
1013
1014
1015
1016
1017
1018 public static String getRequestStringFromMap(Map<String, String> requestParameters) {
1019 String requestString = "";
1020
1021 if (requestParameters.isEmpty()) {
1022 return requestString;
1023 }
1024
1025 URLCodec urlCodec = new URLCodec(KRADConstants.DEFAULT_ENCODING);
1026
1027 for (String key : requestParameters.keySet()) {
1028 String value = null;
1029 try {
1030 value = urlCodec.encode(requestParameters.get(key));
1031 } catch (EncoderException e) {
1032 throw new RuntimeException("Unable to encode parameter name or value: " + key + "=" + value, e);
1033 }
1034
1035 if (StringUtils.isNotBlank(requestString)) {
1036 requestString = requestString + "&";
1037 }
1038
1039 requestString = requestString + key + "=" + value;
1040 }
1041
1042 return "?" + requestString;
1043 }
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055 public static void addAttachmentToResponse(HttpServletResponse response, InputStream inputStream,
1056 String contentType, String fileName, long fileSize) throws IOException {
1057
1058
1059
1060 String updateFileName;
1061 if (fileName.contains("\"")) {
1062 updateFileName = fileName.replaceAll("\"", "");
1063 } else {
1064 updateFileName = fileName;
1065 }
1066
1067
1068 response.setContentType(contentType);
1069 response.setContentLength(org.springframework.util.NumberUtils.convertNumberToTargetClass(fileSize,
1070 Integer.class));
1071 response.setHeader("Content-disposition", "attachment; filename=\"" + updateFileName + "\"");
1072 response.setHeader("Expires", "0");
1073 response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
1074 response.setHeader("Pragma", "public");
1075
1076
1077 if (inputStream != null) {
1078 FileCopyUtils.copy(inputStream, response.getOutputStream());
1079 }
1080 }
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091 public static String buildViewUrl(String baseUrl, String controllerMapping, String viewId) {
1092 Assert.hasLength(baseUrl, "base url is null or empty");
1093 Assert.hasLength(controllerMapping, "controller mapping is null or empty");
1094 Assert.hasLength(viewId, "view id is null or empty");
1095
1096 StringBuffer url = new StringBuffer();
1097
1098 url.append(baseUrl);
1099
1100 if (!baseUrl.endsWith("/")) {
1101 url.append("/");
1102 }
1103
1104 url.append(controllerMapping);
1105
1106 url.append("?");
1107 url.append(UifParameters.VIEW_ID);
1108 url.append("=");
1109 url.append(viewId);
1110
1111 return url.toString();
1112 }
1113
1114
1115
1116
1117
1118
1119
1120 public static void cleanRequestParameters(Properties requestParameters) {
1121 requestParameters.remove(UifParameters.SESSION_ID);
1122 requestParameters.remove(UifParameters.AJAX_REQUEST);
1123 requestParameters.remove(UifParameters.AJAX_RETURN_TYPE);
1124 requestParameters.remove(UifParameters.FORM_KEY);
1125 requestParameters.remove(UifParameters.JUMP_TO_ID);
1126 requestParameters.remove(UifParameters.FOCUS_ID);
1127 }
1128
1129
1130
1131
1132
1133
1134
1135 public static String getFullURL(HttpServletRequest request) {
1136 if (request == null) {
1137 return null;
1138 }
1139
1140 StringBuffer requestURL = request.getRequestURL();
1141 String queryString = request.getQueryString();
1142
1143 if (queryString == null) {
1144 return requestURL.toString();
1145 } else {
1146 return requestURL.append('?').append(queryString).toString();
1147 }
1148 }
1149
1150
1151
1152
1153
1154
1155
1156
1157 public static boolean areDifferentDomains(String firstDomain, String secondDomain) {
1158 try {
1159 URL urlOne = new URL(firstDomain.toLowerCase());
1160 URL urlTwo = new URL(secondDomain.toLowerCase());
1161
1162 if (urlOne.getHost().equals(urlTwo.getHost())) {
1163 LOG.debug("Hosts "
1164 + urlOne.getHost()
1165 + " of domains "
1166 + firstDomain
1167 + " and "
1168 + secondDomain
1169 + " were determined to be equal");
1170
1171 return false;
1172 } else {
1173 LOG.debug("Hosts "
1174 + urlOne.getHost()
1175 + " of domains "
1176 + firstDomain
1177 + " and "
1178 + secondDomain
1179 + " are not equal");
1180
1181 return true;
1182 }
1183 } catch (MalformedURLException mue) {
1184 LOG.error("Unable to successfully compare domains " + firstDomain + " and " + secondDomain);
1185 }
1186
1187 return true;
1188 }
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200 public static String generateUniqueViewTitle(UifFormBase form, View view) {
1201 String title = view.getHeader().getHeaderText();
1202
1203 String viewLabelPropertyName = "";
1204
1205 Class<?> dataObjectClass;
1206 if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
1207 dataObjectClass = ObjectPropertyUtils.getPropertyType(form, view.getDefaultBindingObjectPath());
1208 } else {
1209 dataObjectClass = view.getFormClass();
1210 }
1211
1212 if (dataObjectClass != null) {
1213 viewLabelPropertyName = KRADServiceLocatorWeb.getLegacyDataAdapter().getTitleAttribute(dataObjectClass);
1214 }
1215
1216 String viewLabelPropertyPath = "";
1217 if (StringUtils.isNotBlank(viewLabelPropertyName)) {
1218
1219 if (!viewLabelPropertyName.startsWith(UifConstants.NO_BIND_ADJUST_PREFIX)) {
1220 if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
1221 viewLabelPropertyPath = view.getDefaultBindingObjectPath() + "." + viewLabelPropertyName;
1222 }
1223 } else {
1224 viewLabelPropertyPath = StringUtils.removeStart(viewLabelPropertyName,
1225 UifConstants.NO_BIND_ADJUST_PREFIX);
1226 }
1227 } else {
1228
1229 if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
1230 dataObjectClass = ViewModelUtils.getObjectClassForMetadata(view, form,
1231 view.getDefaultBindingObjectPath());
1232 } else {
1233 dataObjectClass = view.getFormClass();
1234 }
1235
1236 if (dataObjectClass != null) {
1237 String titleAttribute = KRADServiceLocatorWeb.getLegacyDataAdapter().getTitleAttribute(dataObjectClass);
1238 if (StringUtils.isNotBlank(titleAttribute)) {
1239 viewLabelPropertyPath = view.getDefaultBindingObjectPath() + "." + titleAttribute;
1240 }
1241 }
1242 }
1243
1244 Object viewLabelPropertyValue = null;
1245 if (StringUtils.isNotBlank(viewLabelPropertyPath) && ObjectPropertyUtils.isReadableProperty(form,
1246 viewLabelPropertyPath)) {
1247 viewLabelPropertyValue = ObjectPropertyUtils.getPropertyValueAsText(form, viewLabelPropertyPath);
1248 }
1249
1250 if (viewLabelPropertyValue != null && StringUtils.isNotBlank(viewLabelPropertyValue.toString()) && StringUtils
1251 .isNotBlank(title)) {
1252 return title + " (" + viewLabelPropertyValue.toString() + ")";
1253 } else {
1254 return title;
1255 }
1256 }
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271 public static String buildAttributeTitleString(String prependText, Class<?> element,
1272 Map<String, String> keyValueMap) {
1273 StringBuffer titleText = new StringBuffer(prependText);
1274
1275 for (String key : keyValueMap.keySet()) {
1276 String fieldVal = keyValueMap.get(key).toString();
1277
1278 titleText.append(" "
1279 + KRADServiceLocatorWeb.getDataDictionaryService().getAttributeLabel(element, key)
1280 + "="
1281 + fieldVal.toString());
1282 }
1283
1284 return titleText.toString();
1285 }
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298 public static String getSimpleFieldValue(Object model, Field field) {
1299 if (field == null) {
1300 return null;
1301 }
1302
1303 String value = null;
1304
1305 if (field instanceof DataField) {
1306 String propertyPath = ((DataField) field).getBindingInfo().getBindingPath();
1307 Object valueObject = null;
1308
1309 if (field.isHidden()) {
1310 return "";
1311 }
1312
1313
1314 if (ObjectPropertyUtils.isReadableProperty(model, propertyPath)) {
1315 valueObject = ObjectPropertyUtils.getPropertyValueAsText(model, propertyPath);
1316 }
1317
1318
1319 if (valueObject != null && !((DataField) field).isApplyMask()) {
1320 value = valueObject.toString();
1321 } else if (valueObject != null && ((DataField) field).isApplyMask()) {
1322 value = ((DataField) field).getMaskFormatter().maskValue(valueObject);
1323 }
1324 } else if (field instanceof ActionField) {
1325 value = ((ActionField) field).getActionLabel();
1326
1327
1328 if (StringUtils.isBlank(value) && ((ActionField) field).getActionImage() != null) {
1329 value = ((ActionField) field).getActionImage().getAltText();
1330 }
1331 } else if (field instanceof LinkField) {
1332 value = ((LinkField) field).getLinkText();
1333 } else if (field instanceof ImageField) {
1334 value = ((ImageField) field).getAltText();
1335 } else if (field instanceof MessageField && ((MessageField) field).getMessage() != null) {
1336 value = ((MessageField) field).getMessage().getMessageText();
1337 } else if (field instanceof SpaceField) {
1338 value = "";
1339 } else if (field instanceof FieldGroup
1340 && ((FieldGroup) field).getGroup() != null
1341 && ((FieldGroup) field).getGroup().getItems() != null
1342 && !((FieldGroup) field).getGroup().getItems().isEmpty()) {
1343
1344 Component firstComponent = ((FieldGroup) field).getGroup().getItems().get(0);
1345
1346
1347 if (firstComponent != null && firstComponent instanceof Field) {
1348 value = getSimpleFieldValue(model, (Field) firstComponent);
1349 } else if (firstComponent instanceof Action && StringUtils.isNotBlank(
1350 ((Action) firstComponent).getActionLabel())) {
1351 value = ((Action) firstComponent).getActionLabel();
1352 } else if (firstComponent instanceof Action && ((Action) firstComponent).getActionImage() != null) {
1353 value = ((Action) firstComponent).getActionImage().getAltText();
1354 } else if (firstComponent instanceof Link) {
1355 value = ((Link) firstComponent).getLinkText();
1356 } else if (firstComponent instanceof Image) {
1357 value = ((Image) firstComponent).getAltText();
1358 } else if (firstComponent instanceof org.kuali.rice.krad.uif.element.Message) {
1359 value = ((org.kuali.rice.krad.uif.element.Message) firstComponent).getMessageText();
1360 } else {
1361 value = null;
1362 }
1363 }
1364
1365 return value;
1366 }
1367
1368
1369
1370
1371
1372
1373
1374 public static String convertToHTMLAttributeSafeString(String message) {
1375 if (StringUtils.isBlank(message)) {
1376 return message;
1377 }
1378
1379 if (message.contains("\"")) {
1380 message = message.replace("\"", """);
1381 }
1382 if (message.contains("'")) {
1383 message = message.replace("'", "'");
1384 }
1385 if (message.contains("\\")) {
1386 message = message.replace("\\", "\");
1387 }
1388
1389 return message;
1390 }
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403 public static String generateRowCssClassString(Map<String, String> conditionalRowCssClasses, int lineIndex,
1404 boolean isOdd, Map<String, Object> lineContext, ExpressionEvaluator expressionEvaluator) {
1405 String rowCss = "";
1406 if (conditionalRowCssClasses == null || conditionalRowCssClasses.isEmpty()) {
1407 return rowCss;
1408 }
1409
1410 for (String cssRule : conditionalRowCssClasses.keySet()) {
1411 if (cssRule.startsWith(UifConstants.EL_PLACEHOLDER_PREFIX) && lineContext != null &&
1412 expressionEvaluator != null) {
1413 String outcome = expressionEvaluator.evaluateExpressionTemplate(lineContext, cssRule);
1414 if (outcome != null && Boolean.parseBoolean(outcome)) {
1415 rowCss = rowCss + " " + conditionalRowCssClasses.get(cssRule);
1416 }
1417 } else if (cssRule.equals(UifConstants.RowSelection.ALL)) {
1418 rowCss = rowCss + " " + conditionalRowCssClasses.get(cssRule);
1419 } else if (cssRule.equals(UifConstants.RowSelection.EVEN) && !isOdd) {
1420 rowCss = rowCss + " " + conditionalRowCssClasses.get(cssRule);
1421 } else if (cssRule.equals(UifConstants.RowSelection.ODD) && isOdd) {
1422 rowCss = rowCss + " " + conditionalRowCssClasses.get(cssRule);
1423 } else if (StringUtils.isNumeric(cssRule) && (lineIndex + 1) == Integer.parseInt(cssRule)) {
1424 rowCss = rowCss + " " + conditionalRowCssClasses.get(cssRule);
1425 }
1426 }
1427
1428 rowCss = StringUtils.removeStart(rowCss, " ");
1429
1430 return rowCss;
1431 }
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445 static public Class easyGetPropertyType(Object object,
1446 String propertyName) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
1447 if (LegacyUtils.useLegacyForObject(object)) {
1448 return PropertyUtils.getPropertyType(object, propertyName);
1449 }
1450 return KradDataServiceLocator.getDataObjectService().wrap(object).getPropertyType(propertyName);
1451 }
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464 public static void setObjectProperty(Object bo, String propertyName,
1465 Object propertyValue) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
1466 Class propertyType = easyGetPropertyType(bo, propertyName);
1467 setObjectProperty(bo, propertyName, propertyType, propertyValue);
1468
1469 }
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483 public static void setObjectProperty(Object bo, String propertyName, Class propertyType,
1484 Object propertyValue) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
1485 KRADServiceLocatorWeb.getLegacyDataAdapter().setObjectProperty(bo, propertyName, propertyType, propertyValue);
1486 }
1487
1488
1489
1490
1491
1492
1493
1494 public static String clean(String string) {
1495 for (SearchOperator op : SearchOperator.QUERY_CHARACTERS) {
1496 string = StringUtils.replace(string, op.op(), KRADConstants.EMPTY_STRING);
1497 }
1498 return string;
1499 }
1500
1501
1502
1503
1504
1505
1506
1507 public static boolean isNull(Object object) {
1508 if (object == null) {
1509 return true;
1510 }
1511 return KRADServiceLocatorWeb.getLegacyDataAdapter().isNull(object);
1512 }
1513
1514
1515
1516
1517
1518
1519
1520 public static boolean isNotNull(Object object) {
1521 return !isNull(object);
1522 }
1523
1524
1525
1526
1527
1528
1529
1530 public static Class materializeClassForProxiedObject(Object object) {
1531 return KRADServiceLocatorWeb.getLegacyDataAdapter().materializeClassForProxiedObject(object);
1532 }
1533
1534
1535
1536
1537
1538
1539
1540
1541 public static void materializeObjects(Collection possiblyProxiedObjects) {
1542 for (Iterator i = possiblyProxiedObjects.iterator(); i.hasNext(); ) {
1543 KRADUtils.isNotNull(i.next());
1544 }
1545 }
1546
1547
1548
1549
1550
1551
1552
1553 public static String getNestedAttributePrefix(String attributeName) {
1554 int lastIndex = PropertyAccessorUtils.getLastNestedPropertySeparatorIndex(attributeName);
1555
1556 return lastIndex != -1 ? StringUtils.substring(attributeName, 0, lastIndex) : StringUtils.EMPTY;
1557 }
1558
1559
1560
1561
1562
1563
1564
1565 public static String getNestedAttributePrimitive(String attributeName) {
1566 int lastIndex = PropertyAccessorUtils.getLastNestedPropertySeparatorIndex(attributeName);
1567
1568 return lastIndex != -1 ? StringUtils.substring(attributeName, lastIndex + 1) : attributeName;
1569 }
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584 public static Object getNestedValue(Object bo, String fieldName) {
1585 return KRADServiceLocatorWeb.getLegacyDataAdapter().getNestedValue(bo, fieldName);
1586 }
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599 public static <T> T createNewObjectFromClass(Class<T> clazz) {
1600 if (clazz == null) {
1601 throw new RuntimeException("BO class was passed in as null");
1602 }
1603 return (T) KRADServiceLocatorWeb.getLegacyDataAdapter().createNewObjectFromClass(clazz);
1604 }
1605
1606 private static KualiModuleService getKualiModuleService() {
1607 if (kualiModuleService == null) {
1608 kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
1609 }
1610 return kualiModuleService;
1611 }
1612
1613
1614
1615
1616
1617
1618
1619
1620 public static void syncClientSideStateForComponent(Component component, Map<String, Object> clientSideState) {
1621
1622 Map<String, Object> componentState = null;
1623 if (component instanceof View) {
1624 componentState = clientSideState;
1625 } else {
1626 if (clientSideState.containsKey(component.getId())) {
1627 componentState = (Map<String, Object>) clientSideState.get(component.getId());
1628 }
1629 }
1630
1631
1632 if ((componentState != null) && (!componentState.isEmpty())) {
1633 Map<String, Annotation> annotatedFields = CopyUtils.getFieldsWithAnnotation(component.getClass(),
1634 ClientSideState.class);
1635
1636 for (Map.Entry<String, Annotation> annotatedField : annotatedFields.entrySet()) {
1637 ClientSideState clientSideStateAnnot = (ClientSideState) annotatedField.getValue();
1638
1639 String variableName = clientSideStateAnnot.variableName();
1640 if (StringUtils.isBlank(variableName)) {
1641 variableName = annotatedField.getKey();
1642 }
1643
1644 if (componentState.containsKey(variableName)) {
1645 Object value = componentState.get(variableName);
1646 ObjectPropertyUtils.setPropertyValue(component, annotatedField.getKey(), value);
1647 }
1648 }
1649 }
1650 }
1651
1652 }