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