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 org.apache.commons.beanutils.PropertyUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.log4j.Logger;
21 import org.apache.ojb.broker.metadata.ClassDescriptor;
22 import org.apache.ojb.broker.metadata.ConnectionRepository;
23 import org.apache.ojb.broker.metadata.DescriptorRepository;
24 import org.apache.ojb.broker.metadata.FieldDescriptor;
25 import org.apache.ojb.broker.metadata.MetadataManager;
26 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
27 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
28 import org.kuali.rice.core.api.exception.RiceRuntimeException;
29 import org.kuali.rice.core.api.util.ClassLoaderUtils;
30 import org.kuali.rice.krad.bo.PersistableBusinessObject;
31 import org.kuali.rice.krad.dao.PersistenceDao;
32 import org.kuali.rice.krad.exception.IntrospectionException;
33 import org.kuali.rice.krad.exception.ObjectNotABusinessObjectRuntimeException;
34 import org.kuali.rice.krad.exception.ReferenceAttributeDoesntExistException;
35 import org.kuali.rice.krad.exception.ReferenceAttributeNotAnOjbReferenceException;
36 import org.kuali.rice.krad.service.PersistenceService;
37 import org.kuali.rice.krad.util.LegacyDataFramework;
38 import org.kuali.rice.krad.util.ObjectUtils;
39 import org.springframework.core.io.DefaultResourceLoader;
40 import org.springframework.transaction.annotation.Transactional;
41
42 import java.beans.PropertyDescriptor;
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.lang.reflect.InvocationTargetException;
46 import java.util.HashMap;
47 import java.util.HashSet;
48 import java.util.Iterator;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Set;
52 import java.util.Vector;
53
54
55
56
57
58
59
60 @Deprecated
61 @Transactional
62 @LegacyDataFramework
63 public class PersistenceServiceOjbImpl extends PersistenceServiceImplBase implements PersistenceService {
64 private static Logger LOG = Logger.getLogger(PersistenceServiceOjbImpl.class);
65 private static final String CLASSPATH_RESOURCE_PREFIX = "classpath:";
66 private PersistenceDao persistenceDao;
67
68 @Override
69 public void clearCache() {
70 persistenceDao.clearCache();
71 }
72
73 @Override
74 public Object resolveProxy(Object o) {
75 return persistenceDao.resolveProxy(o);
76 }
77
78 @Override
79 public void loadRepositoryDescriptor(String ojbRepositoryFilePath) {
80 if ( LOG.isInfoEnabled() ) {
81 LOG.info("Begin loading OJB Metadata for: " + ojbRepositoryFilePath);
82 }
83 DefaultResourceLoader resourceLoader = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader());
84 InputStream is = null;
85 try {
86 is = resourceLoader.getResource(CLASSPATH_RESOURCE_PREFIX + ojbRepositoryFilePath).getInputStream();
87 ConnectionRepository cr = MetadataManager.getInstance().readConnectionRepository(is);
88 MetadataManager.getInstance().mergeConnectionRepository(cr);
89
90 is = resourceLoader.getResource(CLASSPATH_RESOURCE_PREFIX + ojbRepositoryFilePath).getInputStream();
91 DescriptorRepository dr = MetadataManager.getInstance().readDescriptorRepository(is);
92 MetadataManager.getInstance().mergeDescriptorRepository(dr);
93
94 if (LOG.isDebugEnabled()) {
95 LOG.debug("--------------------------------------------------------------------------");
96 LOG.debug("Merging repository descriptor: " + ojbRepositoryFilePath);
97 LOG.debug("--------------------------------------------------------------------------");
98 }
99 } catch (IOException ioe) {
100 if (is != null) {
101 try {
102 is.close();
103 } catch (IOException e) {
104 LOG.warn("Failed to close InputStream on OJB repository path " + ojbRepositoryFilePath, e);
105 }
106 }
107 throw new RiceRuntimeException(ioe);
108 } finally {
109 if (is != null) {
110 try {
111 is.close();
112 } catch (IOException e) {
113 LOG.warn("Failed to close InputStream on OJB repository path " + ojbRepositoryFilePath, e);
114 }
115 }
116 }
117 if ( LOG.isInfoEnabled() ) {
118 LOG.info("Finished loading OJB Metadata for: " + ojbRepositoryFilePath);
119 }
120 }
121
122
123
124
125 @Override
126 public void retrieveNonKeyFields(Object persistableObject) {
127 if (persistableObject == null) {
128 throw new IllegalArgumentException("invalid (null) persistableObject");
129 }
130 if ( LOG.isDebugEnabled() ) {
131 LOG.debug("retrieving non-key fields for " + persistableObject);
132 }
133
134 persistenceDao.retrieveAllReferences(persistableObject);
135 }
136
137
138
139
140
141 @Override
142 public void retrieveReferenceObject(Object persistableObject, String referenceObjectName) {
143 if (persistableObject == null) {
144 throw new IllegalArgumentException("invalid (null) persistableObject");
145 }
146 if ( LOG.isDebugEnabled() ) {
147 LOG.debug("retrieving reference object " + referenceObjectName + " for " + persistableObject);
148 }
149 persistenceDao.retrieveReference(persistableObject, referenceObjectName);
150 }
151
152
153
154
155
156 @Override
157 public void retrieveReferenceObjects(Object persistableObject, List referenceObjectNames) {
158 if (persistableObject == null) {
159 throw new IllegalArgumentException("invalid (null) persistableObject");
160 }
161 if (referenceObjectNames == null) {
162 throw new IllegalArgumentException("invalid (null) referenceObjectNames");
163 }
164 if (referenceObjectNames.isEmpty()) {
165 throw new IllegalArgumentException("invalid (empty) referenceObjectNames");
166 }
167
168 int index = 0;
169 for (Iterator i = referenceObjectNames.iterator(); i.hasNext(); index++) {
170 String referenceObjectName = (String) i.next();
171 if (StringUtils.isBlank(referenceObjectName)) {
172 throw new IllegalArgumentException("invalid (blank) name at position " + index);
173 }
174
175 retrieveReferenceObject(persistableObject, referenceObjectName);
176 }
177 }
178
179
180
181
182
183 @Override
184 public void retrieveReferenceObjects(List persistableObjects, List referenceObjectNames) {
185 if (persistableObjects == null) {
186 throw new IllegalArgumentException("invalid (null) persistableObjects");
187 }
188 if (persistableObjects.isEmpty()) {
189 throw new IllegalArgumentException("invalid (empty) persistableObjects");
190 }
191 if (referenceObjectNames == null) {
192 throw new IllegalArgumentException("invalid (null) referenceObjectNames");
193 }
194 if (referenceObjectNames.isEmpty()) {
195 throw new IllegalArgumentException("invalid (empty) referenceObjectNames");
196 }
197
198 for (Iterator i = persistableObjects.iterator(); i.hasNext();) {
199 Object persistableObject = i.next();
200 retrieveReferenceObjects(persistableObject, referenceObjectNames);
201 }
202 }
203
204
205
206
207
208 @Override
209 public String getFlattenedPrimaryKeyFieldValues(Object persistableObject) {
210 if (persistableObject == null) {
211 throw new IllegalArgumentException("invalid (null) persistableObject");
212 }
213 Map primaryKeyValues = getPrimaryKeyFieldValues(persistableObject, true);
214
215 StringBuffer flattened = new StringBuffer(persistableObject.getClass().getName());
216 flattened.append("(");
217 for (Iterator i = primaryKeyValues.entrySet().iterator(); i.hasNext();) {
218 Map.Entry e = (Map.Entry) i.next();
219
220 String fieldName = (String) e.getKey();
221 Object fieldValue = e.getValue();
222
223 flattened.append(fieldName + "=" + fieldValue);
224 if (i.hasNext()) {
225 flattened.append(",");
226 }
227 }
228
229 flattened.append(")");
230
231 return flattened.toString();
232
233 }
234
235 private void linkObjectsWithCircularReferenceCheck(Object persistableObject, Set referenceSet) {
236 if (ObjectUtils.isNull(persistableObject) || referenceSet.contains(persistableObject)) {
237 return;
238 }
239 referenceSet.add(persistableObject);
240 ClassDescriptor classDescriptor = getClassDescriptor(persistableObject.getClass());
241
242 String className = null;
243 String fieldName = null;
244 try {
245
246 Vector objectReferences = classDescriptor.getObjectReferenceDescriptors();
247 for (Iterator iter = objectReferences.iterator(); iter.hasNext();) {
248 ObjectReferenceDescriptor referenceDescriptor = (ObjectReferenceDescriptor) iter.next();
249
250
251 className = persistableObject.getClass().getName();
252 fieldName = referenceDescriptor.getAttributeName();
253 Object referenceObject = PropertyUtils.getProperty(persistableObject, fieldName);
254 if (ObjectUtils.isNull(referenceObject) || referenceSet.contains(referenceObject)) {
255 continue;
256 }
257
258
259 linkObjectsWithCircularReferenceCheck(referenceObject, referenceSet);
260
261
262
263 FieldDescriptor[] refFkNames = referenceDescriptor.getForeignKeyFieldDescriptors(classDescriptor);
264 ClassDescriptor refCld = getClassDescriptor(referenceDescriptor.getItemClass());
265 FieldDescriptor[] refPkNames = refCld.getPkFields();
266
267 Map objFkValues = new HashMap();
268 for (int i = 0; i < refPkNames.length; i++) {
269 objFkValues.put(refFkNames[i].getAttributeName(), ObjectUtils.getPropertyValue(referenceObject, refPkNames[i].getAttributeName()));
270 }
271
272 for (int i = 0; i < refFkNames.length; i++) {
273 FieldDescriptor fkField = refFkNames[i];
274 String fkName = fkField.getAttributeName();
275
276
277
278 Object fkValue = null;
279 if (objFkValues.containsKey(fkName)) {
280 fkValue = objFkValues.get(fkName);
281 }
282
283
284 Object mainFkValue = ObjectUtils.getPropertyValue(persistableObject, fkName);
285 if (ObjectUtils.isNotNull(mainFkValue) && StringUtils.isNotBlank(mainFkValue.toString())) {
286 fkValue = mainFkValue;
287 } else if (ObjectUtils.isNull(fkValue) || StringUtils.isBlank(fkValue.toString())) {
288
289
290 for (Iterator iter2 = objectReferences.iterator(); iter2.hasNext();) {
291 ObjectReferenceDescriptor checkDescriptor = (ObjectReferenceDescriptor) iter2.next();
292
293 fkValue = getReferenceFKValue(persistableObject, checkDescriptor, fkName);
294 if (ObjectUtils.isNotNull(fkValue) && StringUtils.isNotBlank(fkValue.toString())) {
295 break;
296 }
297 }
298 }
299
300
301 if (ObjectUtils.isNotNull(fkValue)) {
302 fieldName = refPkNames[i].getAttributeName();
303 ObjectUtils.setObjectProperty(referenceObject, fieldName, fkValue.getClass(), fkValue);
304
305
306 if (ObjectUtils.isNull(mainFkValue)) {
307 ObjectUtils.setObjectProperty(persistableObject, fkName, fkValue.getClass(), fkValue);
308 }
309 }
310 }
311 }
312 } catch (NoSuchMethodException e) {
313 throw new IntrospectionException("no setter for property '" + className + "." + fieldName + "'", e);
314 } catch (IllegalAccessException e) {
315 throw new IntrospectionException("problem accessing property '" + className + "." + fieldName + "'", e);
316 } catch (InvocationTargetException e) {
317 throw new IntrospectionException("problem invoking getter for property '" + className + "." + fieldName + "'", e);
318 }
319 }
320
321
322
323
324
325
326
327
328
329
330
331
332 @Override
333 public void linkObjects(Object persistableObject) {
334 linkObjectsWithCircularReferenceCheck(persistableObject, new HashSet());
335 }
336
337
338
339
340
341
342 @Override
343 public boolean allForeignKeyValuesPopulatedForReference(PersistableBusinessObject bo, String referenceName) {
344
345 boolean allFkeysHaveValues = true;
346
347
348 if (bo == null) {
349 throw new IllegalArgumentException("The Class passed in for the BusinessObject argument was null.");
350 }
351 if (StringUtils.isBlank(referenceName)) {
352 throw new IllegalArgumentException("The String passed in for the referenceName argument was null or empty.");
353 }
354
355 PropertyDescriptor propertyDescriptor = null;
356
357
358 try {
359 propertyDescriptor = PropertyUtils.getPropertyDescriptor(bo, referenceName);
360 } catch (Exception e) {
361 throw new RuntimeException(e);
362 }
363 if (propertyDescriptor == null) {
364 throw new ReferenceAttributeDoesntExistException("Requested attribute: '" + referenceName + "' does not exist " + "on class: '" + bo.getClass().getName() + "'.");
365 }
366
367
368 Class referenceClass = getBusinessObjectAttributeClass( bo.getClass(), referenceName );
369 if ( referenceClass == null ) {
370 referenceClass = propertyDescriptor.getPropertyType();
371 }
372
373
374
375 if (!PersistableBusinessObject.class.isAssignableFrom(referenceClass)) {
376 throw new ObjectNotABusinessObjectRuntimeException("Attribute requested (" + referenceName + ") is of class: " + "'" + referenceClass.getName() + "' and is not a " + "descendent of BusinessObject. Only descendents of BusinessObject "
377 + "can be used.");
378 }
379
380
381
382
383 ClassDescriptor classDescriptor = getClassDescriptor(bo.getClass());
384 ObjectReferenceDescriptor referenceDescriptor = classDescriptor.getObjectReferenceDescriptorByName(referenceName);
385 if (referenceDescriptor == null) {
386 throw new ReferenceAttributeNotAnOjbReferenceException("Attribute requested (" + referenceName + ") is not listed " + "in OJB as a reference-descriptor for class: '" + bo.getClass().getName() + "'");
387 }
388
389
390
391 Vector fkFields = referenceDescriptor.getForeignKeyFields();
392 Iterator fkIterator = fkFields.iterator();
393
394
395 while (fkIterator.hasNext()) {
396
397
398 String fkFieldName = (String) fkIterator.next();
399
400
401 Object fkFieldValue = null;
402 try {
403 fkFieldValue = PropertyUtils.getSimpleProperty(bo, fkFieldName);
404 }
405
406
407
408 catch (IllegalAccessException e) {
409 return false;
410 } catch (InvocationTargetException e) {
411 return false;
412 } catch (NoSuchMethodException e) {
413 return false;
414 }
415
416
417 if (fkFieldValue == null) {
418 return false;
419 } else if (String.class.isAssignableFrom(fkFieldValue.getClass())) {
420 if (StringUtils.isBlank((String) fkFieldValue)) {
421 return false;
422 }
423 }
424 }
425
426 return allFkeysHaveValues;
427 }
428
429
430
431
432
433 @Override
434 public void refreshAllNonUpdatingReferences(PersistableBusinessObject bo) {
435
436
437 ClassDescriptor classDescriptor = getClassDescriptor(bo.getClass());
438
439
440 Vector references = classDescriptor.getObjectReferenceDescriptors();
441
442
443 for (Iterator iter = references.iterator(); iter.hasNext();) {
444 ObjectReferenceDescriptor reference = (ObjectReferenceDescriptor) iter.next();
445
446
447 if (reference.getCascadingStore() == ObjectReferenceDescriptor.CASCADE_NONE) {
448 PersistentField persistentField = reference.getPersistentField();
449 String referenceName = persistentField.getName();
450 retrieveReferenceObject(bo, referenceName);
451 }
452 }
453 }
454
455 private Object getReferenceFKValue(Object persistableObject, ObjectReferenceDescriptor chkRefCld, String fkName) {
456 ClassDescriptor classDescriptor = getClassDescriptor(persistableObject.getClass());
457 Object referenceObject = ObjectUtils.getPropertyValue(persistableObject, chkRefCld.getAttributeName());
458
459 if (referenceObject == null) {
460 return null;
461 }
462
463 FieldDescriptor[] refFkNames = chkRefCld.getForeignKeyFieldDescriptors(classDescriptor);
464 ClassDescriptor refCld = getClassDescriptor(chkRefCld.getItemClass());
465 FieldDescriptor[] refPkNames = refCld.getPkFields();
466
467
468 Object fkValue = null;
469 for (int i = 0; i < refFkNames.length; i++) {
470 FieldDescriptor fkField = refFkNames[i];
471
472 if (fkField.getAttributeName().equals(fkName)) {
473 fkValue = ObjectUtils.getPropertyValue(referenceObject, refPkNames[i].getAttributeName());
474 break;
475 }
476 }
477
478 return fkValue;
479 }
480
481
482
483
484
485
486 @Override
487 public boolean isProxied(Object object) {
488 return persistenceDao.isProxied(object);
489 }
490
491
492
493
494
495
496
497 public void setPersistenceDao(PersistenceDao persistenceDao) {
498 this.persistenceDao = persistenceDao;
499 }
500 }