1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.module.purap.util;
17
18 import org.kuali.ole.module.purap.PurapConstants;
19 import org.kuali.ole.sys.context.SpringContext;
20 import org.kuali.rice.core.web.format.FormatException;
21 import org.kuali.rice.krad.bo.BusinessObject;
22 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
23 import org.kuali.rice.krad.service.KualiModuleService;
24 import org.kuali.rice.krad.service.ModuleService;
25 import org.kuali.rice.krad.service.PersistenceService;
26 import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
27 import org.kuali.rice.krad.util.ObjectUtils;
28
29 import java.lang.reflect.Field;
30 import java.lang.reflect.InvocationTargetException;
31 import java.lang.reflect.Modifier;
32 import java.util.*;
33
34
35
36
37
38
39 public class PurApObjectUtils {
40 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurApObjectUtils.class);
41
42
43
44
45
46
47
48
49
50 public static void populateFromBaseClass(Class base, BusinessObject src, BusinessObject target, Map supplementalUncopyable) {
51 List<String> fieldNames = new ArrayList<String>();
52 Field[] fields = base.getDeclaredFields();
53
54
55 for (Field field : fields) {
56 if (!Modifier.isTransient(field.getModifiers())) {
57 fieldNames.add(field.getName());
58 } else {
59 if (LOG.isDebugEnabled()) {
60 LOG.debug("field " + field.getName() + " is transient, skipping ");
61 }
62 }
63 }
64 int counter = 0;
65 for (String fieldName : fieldNames) {
66 if ((isProcessableField(base, fieldName, PurapConstants.KNOWN_UNCOPYABLE_FIELDS)) && (isProcessableField(base, fieldName, supplementalUncopyable))) {
67 attemptCopyOfFieldName(base.getName(), fieldName, src, target, supplementalUncopyable);
68 counter++;
69 }
70 }
71 if (LOG.isDebugEnabled()) {
72 LOG.debug("Population complete for " + counter + " fields out of a total of " + fieldNames.size() + " potential fields in object with base class '" + base + "'");
73 }
74 }
75
76
77
78
79
80
81
82
83
84 protected static boolean isProcessableField(Class baseClass, String fieldName, Map excludedFieldNames) {
85 if (excludedFieldNames.containsKey(fieldName)) {
86 Class potentialClassName = (Class) excludedFieldNames.get(fieldName);
87 if ((ObjectUtils.isNull(potentialClassName)) || (potentialClassName.equals(baseClass))) {
88 return false;
89 }
90 }
91 return true;
92 }
93
94
95
96
97
98
99
100
101
102
103 protected static void attemptCopyOfFieldName(String baseClassName, String fieldName, BusinessObject sourceObject, BusinessObject targetObject, Map supplementalUncopyable) {
104 try {
105
106 Object propertyValue = ObjectUtils.getPropertyValue(sourceObject, fieldName);
107 if ((ObjectUtils.isNotNull(propertyValue)) && (Collection.class.isAssignableFrom(propertyValue.getClass()))) {
108 if (LOG.isDebugEnabled()) {
109 LOG.debug("attempting to copy collection field '" + fieldName + "' using base class '" + baseClassName + "' and property value class '" + propertyValue.getClass() + "'");
110 }
111 copyCollection(fieldName, targetObject, (Collection) propertyValue, supplementalUncopyable);
112 } else {
113 String propertyValueClass = (ObjectUtils.isNotNull(propertyValue)) ? propertyValue.getClass().toString() : "(null)";
114 if (LOG.isDebugEnabled()) {
115 LOG.debug("attempting to set field '" + fieldName + "' using base class '" + baseClassName + "' and property value class '" + propertyValueClass + "'");
116 }
117 ObjectUtils.setObjectProperty(targetObject, fieldName, propertyValue);
118 }
119 } catch (Exception e) {
120
121
122
123 if (LOG.isDebugEnabled()) {
124 LOG.debug("couldn't set field '" + fieldName + "' using base class '" + baseClassName + "' due to exception with class name '" + e.getClass().getName() + "'", e);
125 }
126 }
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140
141 protected static <T extends BusinessObject> void copyCollection(String fieldName, BusinessObject targetObject, Collection<T> sourceList, Map supplementalUncopyable) throws FormatException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
142 Collection listToSet = null;
143
144
145 if (ObjectUtils.isNotNull(sourceList)) {
146 ObjectUtils.materializeObjects(sourceList);
147 }
148
149
150
151
152 try {
153 listToSet = sourceList.getClass().newInstance();
154 } catch (Exception e) {
155 if (LOG.isDebugEnabled()) {
156 LOG.debug("couldn't set class '" + sourceList.getClass() + "' on collection..." + fieldName + " using " + sourceList.getClass());
157 }
158 listToSet = new ArrayList<T>();
159 }
160
161
162 for (Iterator iterator = sourceList.iterator(); iterator.hasNext(); ) {
163 BusinessObject sourceCollectionObject = (BusinessObject) iterator.next();
164 if (LOG.isDebugEnabled()) {
165 LOG.debug("attempting to copy collection member with class '" + sourceCollectionObject.getClass() + "'");
166 }
167 BusinessObject targetCollectionObject = (BusinessObject) createNewObjectFromClass(sourceCollectionObject.getClass());
168 populateFromBaseWithSuper(sourceCollectionObject, targetCollectionObject, supplementalUncopyable, new HashSet<Class>());
169
170 Map pkMap = SpringContext.getBean(PersistenceService.class).getPrimaryKeyFieldValues(targetCollectionObject);
171 Set<String> pkFields = pkMap.keySet();
172 for (String field : pkFields) {
173 ObjectUtils.setObjectProperty(targetCollectionObject, field, null);
174 }
175 listToSet.add(targetCollectionObject);
176 }
177 ObjectUtils.setObjectProperty(targetObject, fieldName, listToSet);
178 }
179
180
181
182
183
184
185
186
187
188
189 protected static Object createNewObjectFromClass(Class clazz) {
190 if (clazz == null) {
191 throw new RuntimeException("BO class was passed in as null");
192 }
193 try {
194 if (clazz.getSuperclass().equals(ExternalizableBusinessObject.class)) {
195 Class eboInterface = ExternalizableBusinessObjectUtils.determineExternalizableBusinessObjectSubInterface(clazz);
196 ModuleService moduleService = SpringContext.getBean(KualiModuleService.class).getResponsibleModuleService(eboInterface);
197 return moduleService.createNewObjectFromExternalizableClass(eboInterface);
198 } else {
199 return clazz.newInstance();
200 }
201 } catch (Exception e) {
202 throw new RuntimeException("Error occured while trying to create a new instance for class " + clazz);
203 }
204 }
205
206
207
208
209
210
211
212
213 public static void populateFromBaseClass(Class base, BusinessObject src, BusinessObject target) {
214 populateFromBaseClass(base, src, target, new HashMap());
215 }
216
217
218
219
220
221
222
223
224
225
226 public static void populateFromBaseWithSuper(BusinessObject sourceObject, BusinessObject targetObject, Map supplementalUncopyableFieldNames, Set<Class> classesToExclude) {
227 List<Class> classesToCopy = new ArrayList<Class>();
228 Class sourceObjectClass = sourceObject.getClass();
229 classesToCopy.add(sourceObjectClass);
230 while (sourceObjectClass.getSuperclass() != null) {
231 sourceObjectClass = sourceObjectClass.getSuperclass();
232 if (!classesToExclude.contains(sourceObjectClass)) {
233 classesToCopy.add(sourceObjectClass);
234 }
235 }
236 for (int i = (classesToCopy.size() - 1); i >= 0; i--) {
237 Class temp = classesToCopy.get(i);
238 populateFromBaseClass(temp, sourceObject, targetObject, supplementalUncopyableFieldNames);
239 }
240 }
241
242
243
244
245
246
247
248
249
250
251 public static BusinessObject retrieveObjectWithIdentitcalKey(Collection controlList, BusinessObject bo) {
252 BusinessObject returnBo = null;
253
254 for (Iterator i = controlList.iterator(); i.hasNext(); ) {
255 BusinessObject listBo = (BusinessObject) i.next();
256 if (equalByKeys(listBo, bo)) {
257 returnBo = listBo;
258 }
259 }
260
261 return returnBo;
262 }
263
264
265
266
267
268
269
270
271 public static boolean equalByKeys(BusinessObject bo1, BusinessObject bo2) {
272 boolean equal = true;
273
274 if (bo1 == null && bo2 == null) {
275 equal = true;
276 } else if (bo1 == null || bo2 == null) {
277 equal = false;
278 } else if (!bo1.getClass().getName().equals(bo2.getClass().getName())) {
279 equal = false;
280 } else {
281 Map bo1Keys = SpringContext.getBean(PersistenceService.class).getPrimaryKeyFieldValues(bo1);
282 Map bo2Keys = SpringContext.getBean(PersistenceService.class).getPrimaryKeyFieldValues(bo2);
283 for (Iterator iter = bo1Keys.keySet().iterator(); iter.hasNext(); ) {
284 String keyName = (String) iter.next();
285 if (bo1Keys.get(keyName) != null && bo2Keys.get(keyName) != null) {
286 if (!bo1Keys.get(keyName).toString().equals(bo2Keys.get(keyName).toString())) {
287 equal = false;
288 }
289 } else {
290
291
292 equal = false;
293 }
294 }
295 }
296
297
298 return equal;
299 }
300
301 }