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