1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.service.impl;
17
18 import java.beans.PropertyDescriptor;
19 import java.lang.reflect.Field;
20 import java.lang.reflect.InvocationTargetException;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 import org.apache.commons.beanutils.PropertyUtils;
28 import org.apache.commons.lang.StringUtils;
29 import org.apache.log4j.Logger;
30 import org.kuali.rice.core.framework.persistence.jpa.metadata.EntityDescriptor;
31 import org.kuali.rice.core.framework.persistence.jpa.metadata.MetadataManager;
32 import org.kuali.rice.core.framework.persistence.jpa.metadata.ObjectDescriptor;
33 import org.kuali.rice.krad.bo.PersistableBusinessObject;
34 import org.kuali.rice.krad.dao.PersistenceDao;
35 import org.kuali.rice.krad.exception.IntrospectionException;
36 import org.kuali.rice.krad.exception.ObjectNotABusinessObjectRuntimeException;
37 import org.kuali.rice.krad.exception.ReferenceAttributeDoesntExistException;
38 import org.kuali.rice.krad.exception.ReferenceAttributeNotAnOjbReferenceException;
39 import org.kuali.rice.krad.service.PersistenceService;
40 import org.kuali.rice.krad.util.ObjectUtils;
41 import org.springframework.transaction.annotation.Transactional;
42
43
44
45
46
47 @Transactional
48 public class PersistenceServiceJpaImpl extends PersistenceServiceImplBase implements PersistenceService {
49
50 private static Logger LOG = Logger.getLogger(PersistenceServiceJpaImpl.class);
51 private PersistenceDao persistenceDao;
52
53 public void setPersistenceDao(PersistenceDao persistenceDao) {
54 this.persistenceDao = persistenceDao;
55 }
56
57
58
59
60 public boolean allForeignKeyValuesPopulatedForReference(PersistableBusinessObject bo, String referenceName) {
61 boolean allFkeysHaveValues = true;
62
63
64 if (bo == null) {
65 throw new IllegalArgumentException("The Class passed in for the BusinessObject argument was null.");
66 }
67 if (StringUtils.isBlank(referenceName)) {
68 throw new IllegalArgumentException("The String passed in for the referenceName argument was null or empty.");
69 }
70
71 PropertyDescriptor propertyDescriptor = null;
72
73
74 try {
75 propertyDescriptor = PropertyUtils.getPropertyDescriptor(bo, referenceName);
76 } catch (Exception e) {
77 throw new RuntimeException(e);
78 }
79 if (propertyDescriptor == null) {
80 throw new ReferenceAttributeDoesntExistException("Requested attribute: '" + referenceName + "' does not exist " + "on class: '" + bo.getClass().getName() + "'.");
81 }
82
83
84 Class referenceClass = getBusinessObjectAttributeClass( bo.getClass(), referenceName );
85 if ( referenceClass == null ) {
86 referenceClass = propertyDescriptor.getPropertyType();
87 }
88
89
90
91 if (!PersistableBusinessObject.class.isAssignableFrom(referenceClass)) {
92 throw new ObjectNotABusinessObjectRuntimeException("Attribute requested (" + referenceName + ") is of class: " + "'" + referenceClass.getName() + "' and is not a " + "descendent of BusinessObject. Only descendents of BusinessObject " + "can be used.");
93 }
94
95 EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(bo.getClass());
96 ObjectDescriptor objectDescriptor = descriptor.getObjectDescriptorByName(referenceName);
97 if (objectDescriptor == null) {
98 throw new ReferenceAttributeNotAnOjbReferenceException("Attribute requested (" + referenceName + ") is not listed " + "in OJB as a reference-descriptor for class: '" + bo.getClass().getName() + "'");
99 }
100
101
102 List fkFields = objectDescriptor.getForeignKeyFields();
103 Iterator fkIterator = fkFields.iterator();
104
105
106 while (fkIterator.hasNext()) {
107
108
109 String fkFieldName = (String) fkIterator.next();
110
111
112 Object fkFieldValue = null;
113 try {
114 fkFieldValue = PropertyUtils.getSimpleProperty(bo, fkFieldName);
115 }
116
117
118
119 catch (IllegalAccessException e) {
120 return false;
121 } catch (InvocationTargetException e) {
122 return false;
123 } catch (NoSuchMethodException e) {
124 return false;
125 }
126
127
128 if (fkFieldValue == null) {
129 return false;
130 } else if (String.class.isAssignableFrom(fkFieldValue.getClass())) {
131 if (StringUtils.isBlank((String) fkFieldValue)) {
132 return false;
133 }
134 }
135 }
136
137 return allFkeysHaveValues;
138 }
139
140
141
142
143 public void clearCache() {
144 persistenceDao.clearCache();
145 }
146
147
148
149
150 public String getFlattenedPrimaryKeyFieldValues(Object persistableObject) {
151 if (persistableObject == null) {
152 throw new IllegalArgumentException("invalid (null) persistableObject");
153 }
154
155 Map primaryKeyValues = getPrimaryKeyFieldValues(persistableObject, true);
156
157 StringBuffer flattened = new StringBuffer(persistableObject.getClass().getName());
158 flattened.append("(");
159 for (Iterator i = primaryKeyValues.entrySet().iterator(); i.hasNext();) {
160 Map.Entry e = (Map.Entry) i.next();
161
162 String fieldName = (String) e.getKey();
163 Object fieldValue = e.getValue();
164
165 flattened.append(fieldName + "=" + fieldValue);
166 if (i.hasNext()) {
167 flattened.append(",");
168 }
169 }
170
171 flattened.append(")");
172
173 return flattened.toString();
174 }
175
176
177
178
179 public void linkObjects(Object persistableObject) {
180 linkObjectsWithCircularReferenceCheck(persistableObject, new HashSet());
181 }
182
183
184
185
186 public void loadRepositoryDescriptor(String ojbRepositoryFilePath) {}
187
188
189
190
191 public void refreshAllNonUpdatingReferences(PersistableBusinessObject bo) {
192 EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(bo.getClass());
193 List<ObjectDescriptor> objectDescriptors = descriptor.getObjectRelationships();
194
195 for (ObjectDescriptor od : objectDescriptors) {
196 if (od.getCascade().length == 0) {
197 retrieveReferenceObject(bo, od.getAttributeName());
198 }
199 }
200 }
201
202
203
204
205 public Object resolveProxy(Object o) {
206 return persistenceDao.resolveProxy(o);
207 }
208
209
210
211
212 public void retrieveNonKeyFields(Object persistableObject) {
213 if (persistableObject == null) {
214 throw new IllegalArgumentException("invalid (null) persistableObject");
215 }
216 LOG.debug("retrieving non-key fields for " + persistableObject);
217
218 persistenceDao.retrieveAllReferences(persistableObject);
219 }
220
221
222
223
224 public void retrieveReferenceObject(Object persistableObject, String referenceObjectName) {
225 if (persistableObject == null) {
226 throw new IllegalArgumentException("invalid (null) persistableObject");
227 }
228 LOG.debug("retrieving reference object " + referenceObjectName + " for " + persistableObject);
229
230 persistenceDao.retrieveReference(persistableObject, referenceObjectName);
231 }
232
233
234
235
236 public void retrieveReferenceObjects(Object persistableObject, List referenceObjectNames) {
237 if (persistableObject == null) {
238 throw new IllegalArgumentException("invalid (null) persistableObject");
239 }
240 if (referenceObjectNames == null) {
241 throw new IllegalArgumentException("invalid (null) referenceObjectNames");
242 }
243 if (referenceObjectNames.isEmpty()) {
244 throw new IllegalArgumentException("invalid (empty) referenceObjectNames");
245 }
246
247 int index = 0;
248 for (Iterator i = referenceObjectNames.iterator(); i.hasNext(); index++) {
249 String referenceObjectName = (String) i.next();
250 if (StringUtils.isBlank(referenceObjectName)) {
251 throw new IllegalArgumentException("invalid (blank) name at position " + index);
252 }
253
254 retrieveReferenceObject(persistableObject, referenceObjectName);
255 }
256 }
257
258
259
260
261 public void retrieveReferenceObjects(List persistableObjects, List referenceObjectNames) {
262 if (persistableObjects == null) {
263 throw new IllegalArgumentException("invalid (null) persistableObjects");
264 }
265 if (persistableObjects.isEmpty()) {
266 throw new IllegalArgumentException("invalid (empty) persistableObjects");
267 }
268 if (referenceObjectNames == null) {
269 throw new IllegalArgumentException("invalid (null) referenceObjectNames");
270 }
271 if (referenceObjectNames.isEmpty()) {
272 throw new IllegalArgumentException("invalid (empty) referenceObjectNames");
273 }
274
275 for (Iterator i = persistableObjects.iterator(); i.hasNext();) {
276 Object persistableObject = i.next();
277 retrieveReferenceObjects(persistableObject, referenceObjectNames);
278 }
279 }
280
281 private void linkObjectsWithCircularReferenceCheck(Object persistableObject, Set referenceSet) {
282 if (ObjectUtils.isNull(persistableObject) || referenceSet.contains(persistableObject)) {
283 return;
284 }
285
286 referenceSet.add(persistableObject);
287
288 EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(persistableObject.getClass());
289
290 String className = null;
291 String fieldName = null;
292 try {
293
294 List<ObjectDescriptor> objectDescriptors = descriptor.getObjectRelationships();
295 for (ObjectDescriptor od : objectDescriptors) {
296
297 className = persistableObject.getClass().getName();
298 fieldName = od.getAttributeName();
299 Object referenceObject = PropertyUtils.getProperty(persistableObject, fieldName);
300 if (ObjectUtils.isNull(referenceObject) || referenceSet.contains(referenceObject)) {
301 continue;
302 }
303
304
305 linkObjectsWithCircularReferenceCheck(referenceObject, referenceSet);
306
307
308 List<String> refFkNames = od.getForeignKeyFields();
309 EntityDescriptor refCld = MetadataManager.getEntityDescriptor(od.getTargetEntity());
310 Set<org.kuali.rice.core.framework.persistence.jpa.metadata.FieldDescriptor> refPkNames = refCld.getPrimaryKeys();
311
312 try {
313 for (String fk : refFkNames) {
314 Field f = referenceObject.getClass().getDeclaredField(fk);
315 f.setAccessible(true);
316 if (ObjectUtils.isNull(f.get(referenceObject))) {
317 Field f2 = persistableObject.getClass().getDeclaredField(fk);
318 f2.setAccessible(true);
319 f.set(referenceObject, f2.get(persistableObject));
320 }
321 }
322 } catch (Exception e) {
323 LOG.error(e.getMessage(), e);
324 }
325 }
326 } catch (NoSuchMethodException e) {
327 throw new IntrospectionException("no setter for property '" + className + "." + fieldName + "'", e);
328 } catch (IllegalAccessException e) {
329 throw new IntrospectionException("problem accessing property '" + className + "." + fieldName + "'", e);
330 } catch (InvocationTargetException e) {
331 throw new IntrospectionException("problem invoking getter for property '" + className + "." + fieldName + "'", e);
332 }
333 }
334
335
336
337
338
339
340 public boolean isProxied(Object object) {
341 return persistenceDao.isProxied(object);
342 }
343 }