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