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 org.apache.commons.beanutils.NestedNullException;
19 import org.apache.commons.beanutils.PropertyUtils;
20 import org.apache.commons.lang.StringUtils;
21 import org.apache.log4j.Logger;
22 import org.apache.ojb.broker.core.proxy.ProxyHelper;
23 import org.hibernate.collection.PersistentBag;
24 import org.hibernate.proxy.HibernateProxy;
25 import org.kuali.rice.core.api.CoreApiServiceLocator;
26 import org.kuali.rice.core.api.encryption.EncryptionService;
27 import org.kuali.rice.core.api.search.SearchOperator;
28 import org.kuali.rice.core.api.util.cache.CopiedObject;
29 import org.kuali.rice.core.web.format.CollectionFormatter;
30 import org.kuali.rice.core.web.format.FormatException;
31 import org.kuali.rice.core.web.format.Formatter;
32 import org.kuali.rice.krad.bo.BusinessObject;
33 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
34 import org.kuali.rice.krad.bo.PersistableBusinessObject;
35 import org.kuali.rice.krad.bo.PersistableBusinessObjectExtension;
36 import org.kuali.rice.krad.exception.ClassNotPersistableException;
37 import org.kuali.rice.krad.service.KRADServiceLocator;
38 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
39 import org.kuali.rice.krad.service.ModuleService;
40 import org.kuali.rice.krad.service.PersistenceStructureService;
41
42 import javax.persistence.EntityNotFoundException;
43 import java.beans.PropertyDescriptor;
44 import java.io.ByteArrayInputStream;
45 import java.io.ByteArrayOutputStream;
46 import java.io.ObjectInputStream;
47 import java.io.ObjectOutputStream;
48 import java.io.Serializable;
49 import java.lang.reflect.Field;
50 import java.lang.reflect.InvocationTargetException;
51 import java.security.GeneralSecurityException;
52 import java.security.MessageDigest;
53 import java.util.Collection;
54 import java.util.Iterator;
55 import java.util.List;
56 import java.util.Map;
57
58
59
60
61
62
63 public final class ObjectUtils {
64 private static final Logger LOG = Logger.getLogger(ObjectUtils.class);
65
66 private ObjectUtils() {
67 throw new UnsupportedOperationException("do not call");
68 }
69
70
71
72
73
74
75
76
77
78
79 public static Serializable deepCopy(Serializable src) {
80 CopiedObject co = deepCopyForCaching(src);
81 return co.getContent();
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95 public static CopiedObject deepCopyForCaching(Serializable src) {
96 CopiedObject co = new CopiedObject();
97
98 co.setContent(src);
99
100 return co;
101 }
102
103
104
105
106
107
108
109 public static byte[] toByteArray(Object object) throws Exception {
110 ObjectOutputStream oos = null;
111 try {
112 ByteArrayOutputStream bos = new ByteArrayOutputStream();
113 oos = new ObjectOutputStream(bos);
114
115 oos.writeObject(object);
116
117 return bos.toByteArray();
118 } catch (Exception e) {
119 LOG.warn("Exception in ObjectUtil = " + e);
120 throw (e);
121 } finally {
122 if (oos != null) {
123 oos.close();
124 }
125 }
126 }
127
128
129
130
131
132
133
134
135 public static Object fromByteArray(byte[] bytes) throws Exception {
136 ObjectInputStream ois = null;
137 try {
138 ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
139 ois = new ObjectInputStream(bis);
140 Object obj = ois.readObject();
141 return obj;
142 } catch (Exception e) {
143 LOG.warn("Exception in ObjectUtil = " + e);
144 throw (e);
145 } finally {
146 if (ois != null) {
147 ois.close();
148 }
149 }
150 }
151
152
153
154
155
156
157
158 public static String getMD5Hash(Object object) throws Exception {
159 try {
160 MessageDigest md = MessageDigest.getInstance("MD5");
161 md.update(toByteArray(object));
162 return new String(md.digest());
163 } catch (Exception e) {
164 LOG.warn(e);
165 throw e;
166 }
167 }
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 public static BusinessObject createHybridBusinessObject(Class businessObjectClass, BusinessObject source,
185 Map<String, String> template) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
186 BusinessObject obj = null;
187 try {
188 ModuleService moduleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
189 businessObjectClass);
190 if (moduleService != null && moduleService.isExternalizable(businessObjectClass)) {
191 obj = (BusinessObject) moduleService.createNewObjectFromExternalizableClass(businessObjectClass);
192 } else {
193 obj = (BusinessObject) businessObjectClass.newInstance();
194 }
195 } catch (Exception e) {
196 throw new RuntimeException("Cannot instantiate " + businessObjectClass.getName(), e);
197 }
198
199 createHybridBusinessObject(obj, source, template);
200
201 return obj;
202 }
203
204 public static void createHybridBusinessObject(BusinessObject businessObject, BusinessObject source,
205 Map<String, String> template) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
206 for (String name : template.keySet()) {
207 String sourcePropertyName = template.get(name);
208 setObjectProperty(businessObject, name, easyGetPropertyType(source, sourcePropertyName), getPropertyValue(
209 source, sourcePropertyName));
210 }
211 }
212
213
214
215
216
217
218
219
220
221
222
223
224
225 static public Class easyGetPropertyType(Object object,
226 String propertyName) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
227
228
229
230
231 return PropertyUtils.getPropertyType(object, propertyName);
232
233 }
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251 public static Class getPropertyType(Object object, String propertyName,
252 PersistenceStructureService persistenceStructureService) {
253 if (object == null || propertyName == null) {
254 throw new RuntimeException("Business object and property name can not be null");
255 }
256
257 Class propertyType = null;
258 try {
259 try {
260
261 propertyType = PropertyUtils.getPropertyType(object, propertyName);
262 } catch (IllegalArgumentException ex) {
263
264 } catch (NoSuchMethodException nsme) {
265
266 }
267
268
269
270
271 if (propertyType != null && propertyType.equals(PersistableBusinessObjectExtension.class)) {
272 propertyType = persistenceStructureService.getBusinessObjectAttributeClass(ProxyHelper.getRealClass(
273 object), propertyName);
274 }
275
276
277 if (null == propertyType && -1 != propertyName.indexOf('.')) {
278 if (null == persistenceStructureService) {
279 LOG.info(
280 "PropertyType couldn't be determined simply and no PersistenceStructureService was given. If you pass in a PersistenceStructureService I can look in other places to try to determine the type of the property.");
281 } else {
282 String prePeriod = StringUtils.substringBefore(propertyName, ".");
283 String postPeriod = StringUtils.substringAfter(propertyName, ".");
284
285 Class prePeriodClass = getPropertyType(object, prePeriod, persistenceStructureService);
286 Object prePeriodClassInstance = prePeriodClass.newInstance();
287 propertyType = getPropertyType(prePeriodClassInstance, postPeriod, persistenceStructureService);
288 }
289
290 } else if (Collection.class.isAssignableFrom(propertyType)) {
291 Map<String, Class> map = persistenceStructureService.listCollectionObjectTypes(object.getClass());
292 propertyType = map.get(propertyName);
293 }
294
295 } catch (Exception e) {
296 LOG.debug("unable to get property type for " + propertyName + " " + e.getMessage());
297
298 }
299
300 return propertyType;
301 }
302
303
304
305
306
307
308
309
310 public static Object getPropertyValue(Object businessObject, String propertyName) {
311 if (businessObject == null || propertyName == null) {
312 throw new RuntimeException("Business object and property name can not be null");
313 }
314
315 Object propertyValue = null;
316 try {
317 propertyValue = PropertyUtils.getProperty(businessObject, propertyName);
318 } catch (NestedNullException e) {
319
320 } catch (IllegalAccessException e1) {
321 LOG.error("error getting property value for " + businessObject.getClass() + "." + propertyName + " " + e1
322 .getMessage());
323 throw new RuntimeException(
324 "error getting property value for " + businessObject.getClass() + "." + propertyName + " " + e1
325 .getMessage(), e1);
326 } catch (InvocationTargetException e1) {
327
328 } catch (NoSuchMethodException e1) {
329 LOG.error("error getting property value for " + businessObject.getClass() + "." + propertyName + " " + e1
330 .getMessage());
331 throw new RuntimeException(
332 "error getting property value for " + businessObject.getClass() + "." + propertyName + " " + e1
333 .getMessage(), e1);
334 }
335
336 return propertyValue;
337 }
338
339
340
341
342
343
344
345
346
347
348 public static String getFormattedPropertyValue(BusinessObject businessObject, String propertyName,
349 Formatter formatter) {
350 String propValue = KRADConstants.EMPTY_STRING;
351
352 Object prop = ObjectUtils.getPropertyValue(businessObject, propertyName);
353 if (formatter == null) {
354 propValue = formatPropertyValue(prop);
355 } else {
356 final Object formattedValue = formatter.format(prop);
357 if (formattedValue != null) {
358 propValue = String.valueOf(formattedValue);
359 }
360 }
361
362 return propValue;
363 }
364
365
366
367
368
369
370
371
372
373
374 public static String getFormattedPropertyValueUsingDataDictionary(BusinessObject businessObject,
375 String propertyName) {
376 Formatter formatter = getFormatterWithDataDictionary(businessObject, propertyName);
377
378 return getFormattedPropertyValue(businessObject, propertyName, formatter);
379 }
380
381
382
383
384
385
386
387
388 public static String formatPropertyValue(Object propertyValue) {
389 Object propValue = KRADConstants.EMPTY_STRING;
390
391 Formatter formatter = null;
392 if (propertyValue != null) {
393 if (propertyValue instanceof Collection) {
394 formatter = new CollectionFormatter();
395 } else {
396 formatter = Formatter.getFormatter(propertyValue.getClass());
397 }
398
399 propValue = formatter != null ? formatter.format(propertyValue) : propertyValue;
400 }
401
402 return propValue != null ? String.valueOf(propValue) : KRADConstants.EMPTY_STRING;
403 }
404
405
406
407
408
409 public static void setObjectProperty(Object bo, String propertyName,
410 Object propertyValue) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
411 Class propertyType = easyGetPropertyType(bo, propertyName);
412 setObjectProperty(bo, propertyName, propertyType, propertyValue);
413 }
414
415
416
417
418
419
420
421
422
423
424
425
426
427 public static void setObjectProperty(Object bo, String propertyName, Class propertyType,
428 Object propertyValue) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
429
430 boolean reformat = false;
431 if (propertyType != null) {
432 if (propertyValue != null && propertyType.isAssignableFrom(String.class)) {
433
434 reformat = true;
435 } else if (propertyValue != null && !propertyType.isAssignableFrom(propertyValue.getClass())) {
436
437 reformat = true;
438 }
439
440
441 if (boolean.class.isAssignableFrom(propertyType) && propertyValue == null) {
442 propertyValue = false;
443 }
444 }
445
446 Formatter formatter = getFormatterWithDataDictionary(bo, propertyName);
447 if (reformat && formatter != null) {
448 LOG.debug("reformatting propertyValue using Formatter " + formatter.getClass().getName());
449 propertyValue = formatter.convertFromPresentationFormat(propertyValue);
450 }
451
452
453 PropertyUtils.setNestedProperty(bo, propertyName, propertyValue);
454 }
455
456
457
458
459
460
461
462
463
464
465
466
467
468 public static void setObjectProperty(Formatter formatter, Object bo, String propertyName, Class type,
469 Object propertyValue) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
470
471
472 if (formatter != null) {
473 propertyValue = formatter.convertFromPresentationFormat(propertyValue);
474 }
475
476
477
478 if (propertyValue instanceof String) {
479 String propVal = (String) propertyValue;
480
481 if (propVal.endsWith(EncryptionService.ENCRYPTION_POST_PREFIX)) {
482 propVal = StringUtils.removeEnd(propVal, EncryptionService.ENCRYPTION_POST_PREFIX);
483 }
484
485 if (KRADServiceLocatorWeb.getDataObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(bo.getClass(), propertyName)) {
486 try {
487 if (CoreApiServiceLocator.getEncryptionService().isEnabled()) {
488 propertyValue = CoreApiServiceLocator.getEncryptionService().decrypt(propVal);
489 }
490 } catch (GeneralSecurityException e) {
491 throw new RuntimeException(e);
492 }
493 }
494 }
495
496
497 PropertyUtils.setNestedProperty(bo, propertyName, propertyValue);
498 }
499
500
501
502
503
504
505
506
507
508
509 public static Formatter getFormatterWithDataDictionary(Object bo, String propertyName) {
510 Formatter formatter = null;
511
512 Class boClass = bo.getClass();
513 String boPropertyName = propertyName;
514
515
516 if (StringUtils.contains(propertyName, "]")) {
517 Object collectionParent = getNestedValue(bo, StringUtils.substringBeforeLast(propertyName, "].") + "]");
518 if (collectionParent != null) {
519 boClass = collectionParent.getClass();
520 boPropertyName = StringUtils.substringAfterLast(propertyName, "].");
521 }
522 }
523
524 Class<? extends Formatter> formatterClass =
525 KRADServiceLocatorWeb.getDataDictionaryService().getAttributeFormatter(boClass, boPropertyName);
526 if (formatterClass == null) {
527 try {
528 formatterClass = Formatter.findFormatter(getPropertyType(boClass.newInstance(), boPropertyName,
529 KRADServiceLocator.getPersistenceStructureService()));
530 } catch (InstantiationException e) {
531 LOG.warn("Unable to find a formater for bo class " + boClass + " and property " + boPropertyName);
532
533 } catch (IllegalAccessException e) {
534 LOG.warn("Unable to find a formater for bo class " + boClass + " and property " + boPropertyName);
535
536 }
537 }
538
539 if (formatterClass != null) {
540 try {
541 formatter = formatterClass.newInstance();
542 } catch (Exception e) {
543 throw new RuntimeException("cannot create new instance of formatter class " + formatterClass.toString(),
544 e);
545 }
546 }
547
548 return formatter;
549 }
550
551
552
553
554
555
556
557
558
559
560
561
562
563 public static void setObjectPropertyDeep(Object bo, String propertyName, Class type,
564 Object propertyValue) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
565
566
567 if (isNull(bo) || !PropertyUtils.isReadable(bo, propertyName) || (propertyValue != null && propertyValue.equals(
568 getPropertyValue(bo, propertyName))) || (type != null && !type.equals(easyGetPropertyType(bo,
569 propertyName)))) {
570 return;
571 }
572
573
574 materializeUpdateableCollections(bo);
575
576
577 setObjectProperty(bo, propertyName, type, propertyValue);
578
579
580 PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(bo.getClass());
581 for (int i = 0; i < propertyDescriptors.length; i++) {
582
583 PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
584
585
586 if (propertyDescriptor.getPropertyType() != null && (BusinessObject.class).isAssignableFrom(
587 propertyDescriptor.getPropertyType()) && PropertyUtils.isReadable(bo,
588 propertyDescriptor.getName())) {
589 Object nestedBo = getPropertyValue(bo, propertyDescriptor.getName());
590 if (nestedBo instanceof BusinessObject) {
591 setObjectPropertyDeep((BusinessObject) nestedBo, propertyName, type, propertyValue);
592 }
593 }
594
595
596 else if (propertyDescriptor.getPropertyType() != null && (List.class).isAssignableFrom(
597 propertyDescriptor.getPropertyType()) && getPropertyValue(bo, propertyDescriptor.getName())
598 != null) {
599
600 List propertyList = (List) getPropertyValue(bo, propertyDescriptor.getName());
601 for (Object listedBo : propertyList) {
602 if (listedBo != null && listedBo instanceof BusinessObject) {
603 setObjectPropertyDeep(listedBo, propertyName, type, propertyValue);
604 }
605 }
606 }
607 }
608 }
609
610
611
612
613 public static void setObjectPropertyDeep(Object bo, String propertyName, Class type, Object propertyValue,
614 int depth) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
615
616 if (depth == 0 || isNull(bo) || !PropertyUtils.isReadable(bo, propertyName)) {
617 return;
618 }
619
620
621 try {
622 materializeUpdateableCollections(bo);
623 } catch(ClassNotPersistableException ex){
624
625 LOG.info("Not persistable dataObjectClass: "+bo.getClass().getName()+", field: "+propertyName);
626 }
627
628
629 setObjectProperty(bo, propertyName, type, propertyValue);
630
631
632 PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(bo.getClass());
633 for (int i = 0; i < propertyDescriptors.length; i++) {
634 PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
635
636
637 if (propertyDescriptor.getPropertyType() != null && (BusinessObject.class).isAssignableFrom(
638 propertyDescriptor.getPropertyType()) && PropertyUtils.isReadable(bo,
639 propertyDescriptor.getName())) {
640 Object nestedBo = getPropertyValue(bo, propertyDescriptor.getName());
641 if (nestedBo instanceof BusinessObject) {
642 setObjectPropertyDeep((BusinessObject) nestedBo, propertyName, type, propertyValue, depth - 1);
643 }
644 }
645
646
647 else if (propertyDescriptor.getPropertyType() != null && (List.class).isAssignableFrom(
648 propertyDescriptor.getPropertyType()) && getPropertyValue(bo, propertyDescriptor.getName())
649 != null) {
650
651 List propertyList = (List) getPropertyValue(bo, propertyDescriptor.getName());
652
653
654 if (propertyList instanceof PersistentBag) {
655 try {
656 PersistentBag bag = (PersistentBag) propertyList;
657 PersistableBusinessObject pbo =
658 (PersistableBusinessObject) KRADServiceLocator.getEntityManagerFactory()
659 .createEntityManager().find(bo.getClass(), bag.getKey());
660 Field field1 = pbo.getClass().getDeclaredField(propertyDescriptor.getName());
661 Field field2 = bo.getClass().getDeclaredField(propertyDescriptor.getName());
662 field1.setAccessible(true);
663 field2.setAccessible(true);
664 field2.set(bo, field1.get(pbo));
665 propertyList = (List) getPropertyValue(bo, propertyDescriptor.getName());
666 ;
667 } catch (Exception e) {
668 LOG.error(e.getMessage(), e);
669 }
670 }
671
672
673 for (Object listedBo : propertyList) {
674 if (listedBo != null && listedBo instanceof BusinessObject) {
675 setObjectPropertyDeep(listedBo, propertyName, type, propertyValue, depth - 1);
676 }
677 }
678 }
679 }
680 }
681
682
683
684
685
686
687
688
689
690
691
692 public static void materializeUpdateableCollections(
693 Object bo) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
694 if (isNotNull(bo)) {
695 PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(bo.getClass());
696 for (int i = 0; i < propertyDescriptors.length; i++) {
697 if (KRADServiceLocator.getPersistenceStructureService().hasCollection(bo.getClass(),
698 propertyDescriptors[i].getName()) && KRADServiceLocator.getPersistenceStructureService()
699 .isCollectionUpdatable(bo.getClass(), propertyDescriptors[i].getName())) {
700 Collection updateableCollection = (Collection) getPropertyValue(bo,
701 propertyDescriptors[i].getName());
702 if ((updateableCollection != null) && ProxyHelper.isCollectionProxy(updateableCollection)) {
703 materializeObjects(updateableCollection);
704 }
705 }
706 }
707 }
708 }
709
710
711
712
713
714
715
716 public static String clean(String string) {
717 for (SearchOperator op : SearchOperator.QUERY_CHARACTERS) {
718 string = StringUtils.replace(string, op.op(), KRADConstants.EMPTY_STRING);
719 }
720 return string;
721 }
722
723
724
725
726
727
728
729
730 public static boolean equalByKeys(PersistableBusinessObject bo1, PersistableBusinessObject bo2) {
731 boolean equal = true;
732
733 if (bo1 == null && bo2 == null) {
734 equal = true;
735 } else if (bo1 == null || bo2 == null) {
736 equal = false;
737 } else if (!bo1.getClass().getName().equals(bo2.getClass().getName())) {
738 equal = false;
739 } else {
740 Map bo1Keys = KRADServiceLocator.getPersistenceService().getPrimaryKeyFieldValues(bo1);
741 Map bo2Keys = KRADServiceLocator.getPersistenceService().getPrimaryKeyFieldValues(bo2);
742 for (Iterator iter = bo1Keys.keySet().iterator(); iter.hasNext(); ) {
743 String keyName = (String) iter.next();
744 if (bo1Keys.get(keyName) != null && bo2Keys.get(keyName) != null) {
745 if (!bo1Keys.get(keyName).toString().equals(bo2Keys.get(keyName).toString())) {
746 equal = false;
747 }
748 } else {
749 equal = false;
750 }
751 }
752 }
753
754 return equal;
755 }
756
757
758
759
760
761
762
763
764
765 public static boolean collectionContainsObjectWithIdentitcalKey(
766 Collection<? extends PersistableBusinessObject> controlList, PersistableBusinessObject bo) {
767 boolean objectExistsInList = false;
768
769 for (Iterator i = controlList.iterator(); i.hasNext(); ) {
770 if (equalByKeys((PersistableBusinessObject) i.next(), bo)) {
771 return true;
772 }
773 }
774
775 return objectExistsInList;
776 }
777
778
779
780
781
782
783
784
785
786 public static int countObjectsWithIdentitcalKey(Collection<? extends PersistableBusinessObject> collection,
787 PersistableBusinessObject bo) {
788
789 int n = 0;
790 for (PersistableBusinessObject item : collection) {
791 if (equalByKeys(item, bo)) {
792 n++;
793 }
794 }
795 return n;
796 }
797
798
799
800
801
802
803
804
805
806
807
808 public static void removeObjectWithIdentitcalKey(Collection<? extends PersistableBusinessObject> controlList,
809 PersistableBusinessObject bo) {
810 for (Iterator<? extends PersistableBusinessObject> i = controlList.iterator(); i.hasNext(); ) {
811 PersistableBusinessObject listBo = i.next();
812 if (equalByKeys(listBo, bo)) {
813 i.remove();
814 }
815 }
816 }
817
818
819
820
821
822
823
824
825
826
827 public static BusinessObject retrieveObjectWithIdentitcalKey(
828 Collection<? extends PersistableBusinessObject> controlList, PersistableBusinessObject bo) {
829 BusinessObject returnBo = null;
830
831 for (Iterator<? extends PersistableBusinessObject> i = controlList.iterator(); i.hasNext(); ) {
832 PersistableBusinessObject listBo = i.next();
833 if (equalByKeys(listBo, bo)) {
834 returnBo = listBo;
835 }
836 }
837
838 return returnBo;
839 }
840
841
842
843
844
845
846
847 public static boolean isNestedAttribute(String attributeName) {
848 boolean isNested = false;
849
850 if (StringUtils.contains(attributeName, ".")) {
851 isNested = true;
852 }
853
854 return isNested;
855 }
856
857
858
859
860
861
862
863 public static String getNestedAttributePrefix(String attributeName) {
864 String prefix = "";
865
866 if (StringUtils.contains(attributeName, ".")) {
867 prefix = StringUtils.substringBeforeLast(attributeName, ".");
868 }
869
870 return prefix;
871 }
872
873
874
875
876
877
878
879 public static String getNestedAttributePrimitive(String attributeName) {
880 String primitive = attributeName;
881
882 if (StringUtils.contains(attributeName, ".")) {
883 primitive = StringUtils.substringAfterLast(attributeName, ".");
884 }
885
886 return primitive;
887 }
888
889
890
891
892
893
894
895
896
897
898
899 public static boolean isNull(Object object) {
900
901
902 if (object == null) {
903 return true;
904 }
905
906
907
908 if (ProxyHelper.isProxy(object) || ProxyHelper.isCollectionProxy(object)) {
909 if (ProxyHelper.getRealObject(object) == null) {
910 return true;
911 }
912 }
913
914
915
916 try {
917 object.equals(null);
918 } catch (EntityNotFoundException e) {
919 return true;
920 }
921
922 return false;
923 }
924
925
926
927
928
929
930
931
932
933
934
935 public static boolean isNotNull(Object object) {
936 return !ObjectUtils.isNull(object);
937 }
938
939
940
941
942
943
944
945 public static Class materializeClassForProxiedObject(Object object) {
946 if (object == null) {
947 return null;
948 }
949
950 if (object instanceof HibernateProxy) {
951 final Class realClass = ((HibernateProxy) object).getHibernateLazyInitializer().getPersistentClass();
952 return realClass;
953 }
954
955 if (ProxyHelper.isProxy(object) || ProxyHelper.isCollectionProxy(object)) {
956 return ProxyHelper.getRealClass(object);
957 }
958
959 return object.getClass();
960 }
961
962
963
964
965
966
967
968
969 public static void materializeObjects(Collection possiblyProxiedObjects) {
970 for (Iterator i = possiblyProxiedObjects.iterator(); i.hasNext(); ) {
971 ObjectUtils.isNotNull(i.next());
972 }
973 }
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993 public static void materializeSubObjectsToDepth(PersistableBusinessObject bo, int depth) {
994 if (bo == null) {
995 throw new IllegalArgumentException("The bo passed in was null.");
996 }
997 if (depth < 0 || depth > 5) {
998 throw new IllegalArgumentException("The depth passed in was out of bounds. Only values "
999 + "between 0 and 5, inclusively, are allowed.");
1000 }
1001
1002
1003 if (depth == 0) {
1004 return;
1005 }
1006
1007
1008 if (ProxyHelper.isProxy(bo)) {
1009 if (!ProxyHelper.isMaterialized(bo)) {
1010 throw new IllegalArgumentException("The bo passed in is an un-materialized proxy, and cannot be used.");
1011 }
1012 }
1013
1014
1015 if (KRADServiceLocator.getPersistenceStructureService().isPersistable(bo.getClass())) {
1016 Map<String, Class> references =
1017 KRADServiceLocator.getPersistenceStructureService().listReferenceObjectFields(bo);
1018
1019
1020 String referenceName = "";
1021 Class referenceClass = null;
1022 Object referenceValue = null;
1023 Object realReferenceValue = null;
1024
1025
1026 for (Iterator iter = references.keySet().iterator(); iter.hasNext(); ) {
1027 referenceName = (String) iter.next();
1028 referenceClass = references.get(referenceName);
1029
1030
1031 referenceValue = getPropertyValue(bo, referenceName);
1032 if (referenceValue != null) {
1033 if (ProxyHelper.isProxy(referenceValue)) {
1034 realReferenceValue = ProxyHelper.getRealObject(referenceValue);
1035 if (realReferenceValue != null) {
1036 try {
1037 setObjectProperty(bo, referenceName, referenceClass, realReferenceValue);
1038 } catch (FormatException e) {
1039 throw new RuntimeException(
1040 "FormatException: could not set the property '" + referenceName + "'.", e);
1041 } catch (IllegalAccessException e) {
1042 throw new RuntimeException(
1043 "IllegalAccessException: could not set the property '" + referenceName + "'.",
1044 e);
1045 } catch (InvocationTargetException e) {
1046 throw new RuntimeException("InvocationTargetException: could not set the property '"
1047 + referenceName
1048 + "'.", e);
1049 } catch (NoSuchMethodException e) {
1050 throw new RuntimeException(
1051 "NoSuchMethodException: could not set the property '" + referenceName + "'.",
1052 e);
1053 }
1054 }
1055 }
1056
1057
1058 if (realReferenceValue instanceof PersistableBusinessObject && depth > 1) {
1059 materializeSubObjectsToDepth((PersistableBusinessObject) realReferenceValue, depth - 1);
1060 }
1061 }
1062
1063 }
1064 }
1065 }
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 public static void materializeAllSubObjects(PersistableBusinessObject bo) {
1082 materializeSubObjectsToDepth(bo, 3);
1083 }
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098 public static Object getNestedValue(Object bo, String fieldName) {
1099
1100 if (bo == null) {
1101 throw new IllegalArgumentException("The bo passed in was null.");
1102 }
1103 if (StringUtils.isBlank(fieldName)) {
1104 throw new IllegalArgumentException("The fieldName passed in was blank.");
1105 }
1106
1107
1108
1109
1110
1111 String[] fieldNameParts = fieldName.split("\\.");
1112 Object currentObject = null;
1113 Object priorObject = bo;
1114 for (int i = 0; i < fieldNameParts.length; i++) {
1115 String fieldNamePart = fieldNameParts[i];
1116
1117 try {
1118 if (fieldNamePart.indexOf("]") > 0) {
1119 currentObject = PropertyUtils.getIndexedProperty(priorObject, fieldNamePart);
1120 } else {
1121 currentObject = PropertyUtils.getSimpleProperty(priorObject, fieldNamePart);
1122 }
1123 } catch (IllegalAccessException e) {
1124 throw new RuntimeException("Caller does not have access to the property accessor method.", e);
1125 } catch (InvocationTargetException e) {
1126 throw new RuntimeException("Property accessor method threw an exception.", e);
1127 } catch (NoSuchMethodException e) {
1128 throw new RuntimeException("The accessor method requested for this property cannot be found.", e);
1129 }
1130
1131
1132 if (ProxyHelper.isProxy(currentObject)) {
1133 currentObject = ProxyHelper.getRealObject(currentObject);
1134 }
1135
1136
1137
1138 if (currentObject == null) {
1139 return currentObject;
1140 }
1141
1142 priorObject = currentObject;
1143 }
1144 return currentObject;
1145 }
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157 public static Object createNewObjectFromClass(Class clazz) {
1158 if (clazz == null) {
1159 throw new RuntimeException("BO class was passed in as null");
1160 }
1161 try {
1162 if (ExternalizableBusinessObject.class.isAssignableFrom(clazz)) {
1163 Class eboInterface =
1164 ExternalizableBusinessObjectUtils.determineExternalizableBusinessObjectSubInterface(clazz);
1165 ModuleService moduleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
1166 eboInterface);
1167 return moduleService.createNewObjectFromExternalizableClass(eboInterface);
1168 } else {
1169 return clazz.newInstance();
1170 }
1171 } catch (Exception e) {
1172 throw new RuntimeException("Error occured while trying to create a new instance for class " + clazz, e);
1173 }
1174 }
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186 public static boolean isWriteable(Object object, String property,
1187 PersistenceStructureService persistenceStructureService) throws IllegalArgumentException {
1188 if (null == object || null == property) {
1189 throw new IllegalArgumentException("Cannot check writeable status with null arguments.");
1190 }
1191
1192
1193 try {
1194 if (!(PropertyUtils.isWriteable(object, property))) {
1195
1196 return isWriteableHelper(object, property, persistenceStructureService);
1197 } else {
1198 return true;
1199 }
1200 } catch (NestedNullException nestedNullException) {
1201
1202
1203
1204 return isWriteableHelper(object, property, persistenceStructureService);
1205 }
1206 }
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217 private static boolean isWriteableHelper(Object object, String property, PersistenceStructureService persistenceStructureService) {
1218 if (property.contains(".")) {
1219 String propertyName = StringUtils.substringBefore(property, ".");
1220
1221
1222 Class<?> c = ObjectUtils.getPropertyType(object, propertyName, persistenceStructureService);
1223
1224 if (c != null) {
1225 Object i = null;
1226
1227
1228 if (Collection.class.isAssignableFrom(c)) {
1229 Map<String, Class> m = persistenceStructureService.listCollectionObjectTypes(object.getClass());
1230 c = m.get(propertyName);
1231 }
1232
1233
1234 try {
1235 i = c.newInstance();
1236 return isWriteable(i, StringUtils.substringAfter(property, "."), persistenceStructureService);
1237 } catch (Exception ex) {
1238 LOG.error("Skipping Criteria: " + property + " - Unable to instantiate class : " + c.getName(), ex);
1239 }
1240 } else {
1241 LOG.error("Skipping Criteria: " + property + " - Unable to determine class for object: "
1242 + object.getClass().getName() + " - " + propertyName);
1243 }
1244 }
1245 return false;
1246 }
1247
1248
1249
1250
1251
1252
1253
1254 public static <T> T newInstance(Class<T> clazz) {
1255 T object = null;
1256 try {
1257 object = clazz.newInstance();
1258 } catch (InstantiationException e) {
1259 LOG.error("Unable to create new instance of class: " + clazz.getName());
1260 throw new RuntimeException(e);
1261 } catch (IllegalAccessException e) {
1262 LOG.error("Unable to create new instance of class: " + clazz.getName());
1263 throw new RuntimeException(e);
1264 }
1265
1266 return object;
1267 }
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278 public static List<Field> getAllFields(List<Field> fields, Class<?> type, Class<?> stopAt) {
1279 for (Field field : type.getDeclaredFields()) {
1280 fields.add(field);
1281 }
1282
1283 if (type.getSuperclass() != null && !type.getName().equals(stopAt.getName())) {
1284 fields = getAllFields(fields, type.getSuperclass(), stopAt);
1285 }
1286
1287 return fields;
1288 }
1289
1290 }