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.InvocationTargetException;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Vector;
27
28 import org.apache.commons.beanutils.PropertyUtils;
29 import org.apache.commons.lang.StringUtils;
30 import org.apache.ojb.broker.metadata.ClassDescriptor;
31 import org.apache.ojb.broker.metadata.CollectionDescriptor;
32 import org.apache.ojb.broker.metadata.FieldDescriptor;
33 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
34 import org.apache.ojb.broker.metadata.SuperReferenceDescriptor;
35 import org.kuali.rice.krad.bo.DataObjectRelationship;
36 import org.kuali.rice.krad.bo.PersistableBusinessObject;
37 import org.kuali.rice.krad.bo.PersistableBusinessObjectBaseAdapter;
38 import org.kuali.rice.krad.exception.ClassNotPersistableException;
39 import org.kuali.rice.krad.exception.IntrospectionException;
40 import org.kuali.rice.krad.exception.ObjectNotABusinessObjectRuntimeException;
41 import org.kuali.rice.krad.exception.ReferenceAttributeDoesntExistException;
42 import org.kuali.rice.krad.exception.ReferenceAttributeNotAnOjbReferenceException;
43 import org.kuali.rice.krad.service.PersistenceStructureService;
44 import org.kuali.rice.krad.util.ForeignKeyFieldsPopulationState;
45 import org.kuali.rice.krad.util.LegacyDataFramework;
46 @Deprecated
47 @LegacyDataFramework
48 public class PersistenceStructureServiceOjbImpl extends PersistenceServiceImplBase implements PersistenceStructureService {
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public static Map<Class, Class> referenceConversionMap = new HashMap<Class, Class>();
66
67
68 private PersistenceStructureService persistenceStructureServiceJpa;
69
70 public PersistenceStructureService getPersistenceStructureServiceJpa() {
71 return this.persistenceStructureServiceJpa;
72 }
73
74 public void setPersistenceStructureServiceJpa(PersistenceStructureService persistenceStructureServiceJpa) {
75 this.persistenceStructureServiceJpa = persistenceStructureServiceJpa;
76 }
77
78
79
80
81
82 @Override
83 public boolean isPersistable(Class clazz) {
84 boolean isPersistable = false;
85 try {
86 if (getClassDescriptor(clazz) != null) {
87 isPersistable = true;
88 }
89 } catch (ClassNotPersistableException e) {
90 isPersistable = false;
91 }
92 return isPersistable;
93 }
94
95
96
97
98
99 @Override
100 public List getPrimaryKeys(Class clazz) {
101 List pkList = new ArrayList();
102 ClassDescriptor classDescriptor = getClassDescriptor(clazz);
103 FieldDescriptor keyDescriptors[] = classDescriptor.getPkFields();
104 for (int i = 0; i < keyDescriptors.length; ++i) {
105 FieldDescriptor keyDescriptor = keyDescriptors[i];
106 pkList.add(keyDescriptor.getAttributeName());
107 }
108 return pkList;
109 }
110
111
112
113
114
115 @Override
116 public List listFieldNames(Class clazz) {
117 List fieldNames = new ArrayList();
118 ClassDescriptor classDescriptor = getClassDescriptor(clazz);
119 FieldDescriptor fieldDescriptors[] = classDescriptor.getFieldDescriptions();
120 for (int i = 0; i < fieldDescriptors.length; ++i) {
121 FieldDescriptor fieldDescriptor = fieldDescriptors[i];
122 fieldNames.add(fieldDescriptor.getAttributeName());
123 }
124 return fieldNames;
125 }
126
127
128
129
130
131 @Override
132 public Object clearPrimaryKeyFields(Object persistableObject) {
133 if (persistableObject == null) {
134 throw new IllegalArgumentException("invalid (null) persistableObject");
135 }
136
137 String className = null;
138 String fieldName = null;
139 try {
140 className = persistableObject.getClass().getName();
141 List fields = listPrimaryKeyFieldNames(persistableObject.getClass());
142 for (Iterator i = fields.iterator(); i.hasNext();) {
143 fieldName = (String) i.next();
144
145 PropertyUtils.setProperty(persistableObject, fieldName, null);
146 }
147
148 if (persistableObject instanceof PersistableBusinessObject) {
149 ((PersistableBusinessObject) persistableObject).setObjectId(null);
150 }
151 } catch (NoSuchMethodException e) {
152 throw new IntrospectionException("no setter for property '" + className + "." + fieldName + "'", e);
153 } catch (IllegalAccessException e) {
154 throw new IntrospectionException("problem accessing property '" + className + "." + fieldName + "'", e);
155 } catch (InvocationTargetException e) {
156 throw new IntrospectionException("problem invoking getter for property '" + className + "." + fieldName + "'", e);
157 }
158
159 return persistableObject;
160 }
161
162
163
164
165
166
167 @Override
168 public List listPersistableSubclasses(Class superclazz) {
169 if (superclazz == null) {
170 throw new IllegalArgumentException("invalid (null) uberclass");
171 }
172
173 Map allDescriptors = getDescriptorRepository().getDescriptorTable();
174 List persistableSubclasses = new ArrayList();
175 for (Iterator i = allDescriptors.entrySet().iterator(); i.hasNext();) {
176 Map.Entry e = (Map.Entry) i.next();
177
178 Class persistableClass = ((ClassDescriptor) e.getValue()).getClassOfObject();
179 if (!superclazz.equals(persistableClass) && superclazz.isAssignableFrom(persistableClass)) {
180 persistableSubclasses.add(persistableClass);
181 }
182 }
183 return persistableSubclasses;
184 }
185
186
187
188
189
190
191 @Override
192 public Map<String, DataObjectRelationship> getRelationshipMetadata(Class persistableClass, String attributeName, String attributePrefix) {
193 if (persistableClass == null) {
194 throw new IllegalArgumentException("invalid (null) persistableClass");
195 }
196 if (StringUtils.isBlank(attributeName)) {
197 throw new IllegalArgumentException("invalid (blank) attributeName");
198 }
199
200 Map<String, DataObjectRelationship> relationships = new HashMap<String, DataObjectRelationship>();
201 ClassDescriptor classDescriptor = getClassDescriptor(persistableClass);
202 Vector<ObjectReferenceDescriptor> references = classDescriptor.getObjectReferenceDescriptors();
203 for (ObjectReferenceDescriptor objRef : references) {
204 Vector fks = objRef.getForeignKeyFields();
205 if (fks.contains(attributeName) || objRef.getAttributeName().equals(attributeName)) {
206 Map<String, String> fkToPkRefs = getForeignKeysForReference(persistableClass, objRef.getAttributeName());
207 DataObjectRelationship rel = new DataObjectRelationship(persistableClass, objRef.getAttributeName(), objRef.getItemClass());
208 for (Map.Entry<String, String> ref : fkToPkRefs.entrySet()) {
209 if (StringUtils.isBlank(attributePrefix)) {
210 rel.getParentToChildReferences().put(ref.getKey(), ref.getValue());
211 } else {
212 rel.getParentToChildReferences().put(attributePrefix + "." + ref.getKey(), ref.getValue());
213 }
214 }
215 relationships.put(objRef.getAttributeName(), rel);
216 }
217 }
218 return relationships;
219 }
220
221
222
223 @Override
224 public Map<String, DataObjectRelationship> getRelationshipMetadata(Class persistableClass, String attributeName) {
225 return getRelationshipMetadata(persistableClass, attributeName, null);
226 }
227
228
229
230
231
232
233 @Override
234 public String getForeignKeyFieldName(Class persistableObjectClass, String attributeName, String pkName) {
235 String fkName = "";
236 ClassDescriptor classDescriptor = getClassDescriptor(persistableObjectClass);
237 ObjectReferenceDescriptor objectReferenceDescriptor = classDescriptor.getObjectReferenceDescriptorByName(attributeName);
238 if (objectReferenceDescriptor == null) {
239 throw new RuntimeException("Attribute name " + attributeName + " is not a valid reference to class " + persistableObjectClass.getName());
240 }
241 ClassDescriptor referenceDescriptor = this.getClassDescriptor(objectReferenceDescriptor.getItemClass());
242
243 FieldDescriptor[] fkFields = objectReferenceDescriptor.getForeignKeyFieldDescriptors(classDescriptor);
244 FieldDescriptor[] pkFields = referenceDescriptor.getPkFields();
245 for (int i = 0; i < pkFields.length; i++) {
246 FieldDescriptor pkField = pkFields[i];
247 if (pkField.getAttributeName().equals(pkName)) {
248 fkName = fkFields[i].getAttributeName();
249 }
250 }
251 return fkName;
252 }
253
254
255
256
257
258
259 @Override
260 public Map getReferencesForForeignKey(Class persistableObjectClass, String attributeName) {
261 Map referenceClasses = new HashMap();
262 if (PersistableBusinessObject.class.isAssignableFrom(persistableObjectClass)) {
263 ClassDescriptor classDescriptor = getClassDescriptor(persistableObjectClass);
264 Vector objectReferences = classDescriptor.getObjectReferenceDescriptors();
265 for (Iterator iter = objectReferences.iterator(); iter.hasNext();) {
266 ObjectReferenceDescriptor referenceDescriptor = (ObjectReferenceDescriptor) iter.next();
267
268
269
270
271
272 FieldDescriptor[] refFkNames = referenceDescriptor.getForeignKeyFieldDescriptors(classDescriptor);
273 for (int i = 0; i < refFkNames.length; i++) {
274 FieldDescriptor fkField = refFkNames[i];
275 if (fkField.getAttributeName().equals(attributeName)) {
276 referenceClasses.put(referenceDescriptor.getAttributeName(), referenceDescriptor.getItemClass());
277 }
278 }
279 }
280 }
281 return referenceClasses;
282 }
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 @Override
302 public Map getForeignKeysForReference(Class clazz, String attributeName) {
303
304 if (clazz == null) {
305 throw new IllegalArgumentException("The Class passed in for the clazz argument was null.");
306 }
307 if (attributeName == null) {
308 throw new IllegalArgumentException("The String passed in for the attributeName argument was null.");
309 }
310
311
312 Class attributeClass = getBusinessObjectAttributeClass(clazz, attributeName);
313 if (attributeClass == null) {
314 throw new ReferenceAttributeDoesntExistException("Requested attribute: '" + attributeName + "' does not exist " + "on class: '" + clazz.getName() + "'.");
315 }
316
317
318
319 if ((!PersistableBusinessObject.class.isAssignableFrom(attributeClass)) &&
320 (!PersistableBusinessObjectBaseAdapter.class.isAssignableFrom(attributeClass))) {
321 throw new ObjectNotABusinessObjectRuntimeException("Attribute requested (" + attributeName +
322 ") is of class: " + "'" + attributeClass.getName() + "' and is not a " +
323 "descendent of BusinessObject. Only descendents of BusinessObject " + "can be used.");
324 }
325
326 Map fkMap = new HashMap();
327
328
329
330
331 ClassDescriptor classDescriptor = getClassDescriptor(clazz);
332 ObjectReferenceDescriptor referenceDescriptor = classDescriptor.getObjectReferenceDescriptorByName(attributeName);
333 if (referenceDescriptor == null) {
334 throw new ReferenceAttributeNotAnOjbReferenceException("Attribute requested (" + attributeName + ") is not listed " + "in OJB as a reference-descriptor for class: '" + clazz.getName() + "'");
335 }
336
337
338
339
340
341
342 if (!attributeClass.equals(referenceDescriptor.getItemClass())) {
343
344 if (referenceConversionMap.containsKey(attributeClass)) {
345 attributeClass = referenceConversionMap.get(attributeClass);
346 } else {
347 throw new RuntimeException("The Class of the Java member [" + attributeClass.getName() + "] '" + attributeName + "' does not match the class of the " + "reference-descriptor [" + referenceDescriptor.getItemClass().getName() + "]. " + "This is an unhandled special case for which special code needs to be written " + "in this class.");
348 }
349 }
350
351
352
353 Vector fkFields = referenceDescriptor.getForeignKeyFields();
354 Iterator fkIterator = fkFields.iterator();
355
356
357
358 List pkFields = getPrimaryKeys(attributeClass);
359 Iterator pkIterator = pkFields.iterator();
360
361
362
363 if (pkFields.size() != fkFields.size()) {
364 throw new RuntimeException("KualiPersistenceStructureService Error: The number of " + "foreign keys doesnt match the number of primary keys. This may be a " + "result of misconfigured OJB-repository files.");
365 }
366
367
368 while (fkIterator.hasNext()) {
369
370
371
372 if (!pkIterator.hasNext()) {
373 throw new RuntimeException("The number of foriegn keys dont match the number of primary " + "keys for the reference '" + attributeName + "', on BO of type '" + clazz.getName() + "'. " + "This should never happen under normal circumstances, as it means that the OJB repository " + "files are misconfigured.");
374 }
375
376
377 String fkFieldName = (String) fkIterator.next();
378 String pkFieldName = (String) pkIterator.next();
379
380
381 fkMap.put(fkFieldName, pkFieldName);
382 }
383
384 return fkMap;
385 }
386
387
388 @Override
389 public Map<String, String> getInverseForeignKeysForCollection(Class boClass, String collectionName) {
390
391 if (boClass == null) {
392 throw new IllegalArgumentException("The Class passed in for the boClass argument was null.");
393 }
394 if (collectionName == null) {
395 throw new IllegalArgumentException("The String passed in for the attributeName argument was null.");
396 }
397
398 PropertyDescriptor propertyDescriptor = null;
399
400
401 Object classInstance;
402 try {
403 classInstance = boClass.newInstance();
404 } catch (Exception e) {
405 throw new RuntimeException(e);
406 }
407
408
409 try {
410 propertyDescriptor = PropertyUtils.getPropertyDescriptor(classInstance, collectionName);
411 } catch (Exception e) {
412 throw new RuntimeException(e);
413 }
414 if (propertyDescriptor == null) {
415 throw new ReferenceAttributeDoesntExistException("Requested attribute: '" + collectionName + "' does not exist " + "on class: '" + boClass.getName() + "'. GFK");
416 }
417
418
419 Class attributeClass = propertyDescriptor.getPropertyType();
420
421
422
423 if (!Collection.class.isAssignableFrom(attributeClass)) {
424 throw new ObjectNotABusinessObjectRuntimeException("Attribute requested (" + collectionName + ") is of class: " + "'" + attributeClass.getName() + "' and is not a " + "descendent of Collection");
425 }
426
427
428
429
430 ClassDescriptor classDescriptor = getClassDescriptor(boClass);
431 CollectionDescriptor collectionDescriptor = classDescriptor.getCollectionDescriptorByName(collectionName);
432
433
434
435
436
437
438 List parentForeignKeys = getPrimaryKeys(boClass);
439 Vector childPrimaryKeysLegacy = collectionDescriptor.getForeignKeyFields();
440
441 if (parentForeignKeys.size() != childPrimaryKeysLegacy.size()) {
442 throw new RuntimeException("The number of keys in the class descriptor and the inverse foreign key mapping for the collection descriptors do not match.");
443 }
444
445 Map<String, String> fkToPkMap = new HashMap<String, String>();
446
447 Iterator pFKIter = parentForeignKeys.iterator();
448 Iterator cPKIterator = childPrimaryKeysLegacy.iterator();
449
450 while (pFKIter.hasNext()) {
451 String parentForeignKey = (String) pFKIter.next();
452 String childPrimaryKey = (String) cPKIterator.next();
453
454 fkToPkMap.put(parentForeignKey, childPrimaryKey);
455 }
456
457 return fkToPkMap;
458 }
459
460
461
462
463
464 @Override
465 public Map getNestedForeignKeyMap(Class persistableObjectClass) {
466 Map fkMap = new HashMap();
467 ClassDescriptor classDescriptor = getClassDescriptor(persistableObjectClass);
468 Vector objectReferences = classDescriptor.getObjectReferenceDescriptors();
469 for (Iterator iter = objectReferences.iterator(); iter.hasNext();) {
470 ObjectReferenceDescriptor objectReferenceDescriptor = (ObjectReferenceDescriptor) iter.next();
471 ClassDescriptor referenceDescriptor = this.getClassDescriptor(objectReferenceDescriptor.getItemClass());
472
473 FieldDescriptor[] fkFields = objectReferenceDescriptor.getForeignKeyFieldDescriptors(classDescriptor);
474 FieldDescriptor[] pkFields = referenceDescriptor.getPkFields();
475 for (int i = 0; i < pkFields.length; i++) {
476 FieldDescriptor pkField = pkFields[i];
477 fkMap.put(objectReferenceDescriptor.getAttributeName() + "." + pkField.getAttributeName(), fkFields[i].getAttributeName());
478 }
479 }
480
481 return fkMap;
482 }
483
484
485
486
487 @Override
488 public boolean hasPrimaryKeyFieldValues(Object persistableObject) {
489 Map keyFields = getPrimaryKeyFieldValues(persistableObject);
490
491 boolean emptyField = false;
492 for (Iterator i = keyFields.entrySet().iterator(); !emptyField && i.hasNext();) {
493 Map.Entry e = (Map.Entry) i.next();
494
495 Object fieldValue = e.getValue();
496 if (fieldValue == null) {
497 emptyField = true;
498 } else if (fieldValue instanceof String) {
499 if (StringUtils.isEmpty((String) fieldValue)) {
500 emptyField = true;
501 } else {
502 emptyField = false;
503 }
504 }
505 }
506
507 return !emptyField;
508 }
509
510
511
512
513
514 @Override
515 public ForeignKeyFieldsPopulationState getForeignKeyFieldsPopulationState(PersistableBusinessObject bo, String referenceName) {
516 boolean allFieldsPopulated = true;
517 boolean anyFieldsPopulated = false;
518 List<String> unpopulatedFields = new ArrayList<String>();
519
520
521 if (bo == null) {
522 throw new IllegalArgumentException("The Class passed in for the BusinessObject argument was null.");
523 }
524 if (StringUtils.isBlank(referenceName)) {
525 throw new IllegalArgumentException("The String passed in for the referenceName argument was null or empty.");
526 }
527
528 PropertyDescriptor propertyDescriptor = null;
529
530
531 try {
532 propertyDescriptor = PropertyUtils.getPropertyDescriptor(bo, referenceName);
533 } catch (Exception e) {
534 throw new RuntimeException(e);
535 }
536 if (propertyDescriptor == null) {
537 throw new ReferenceAttributeDoesntExistException("Requested attribute: '" + referenceName + "' does not exist " + "on class: '" + bo.getClass().getName() + "'.");
538 }
539
540
541 Class referenceClass = propertyDescriptor.getPropertyType();
542
543
544
545 if (!PersistableBusinessObject.class.isAssignableFrom(referenceClass)) {
546 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.");
547 }
548
549
550
551
552
553 ClassDescriptor classDescriptor = getClassDescriptor(bo.getClass());
554
555
556 ObjectReferenceDescriptor referenceDescriptor = classDescriptor.getObjectReferenceDescriptorByName(referenceName);
557 if (referenceDescriptor == null) {
558 throw new ReferenceAttributeNotAnOjbReferenceException("Attribute requested (" + referenceName + ") is not listed " + "in OJB as a reference-descriptor for class: '" + bo.getClass().getName() + "'");
559 }
560
561
562 Vector fkFieldsLegacy = referenceDescriptor.getForeignKeyFields();
563 Iterator fkIteratorLegacy = fkFieldsLegacy.iterator();
564
565
566 while (fkIteratorLegacy.hasNext()) {
567
568
569 String fkFieldName = (String) fkIteratorLegacy.next();
570
571
572 Object fkFieldValue = null;
573 try {
574 fkFieldValue = PropertyUtils.getSimpleProperty(bo, fkFieldName);
575 }
576
577
578 catch (Exception e) {
579 throw new RuntimeException(e);
580 }
581
582
583 if (fkFieldValue == null) {
584 allFieldsPopulated = false;
585 unpopulatedFields.add(fkFieldName);
586 } else if (fkFieldValue instanceof String) {
587 if (StringUtils.isBlank((String) fkFieldValue)) {
588 allFieldsPopulated = false;
589 unpopulatedFields.add(fkFieldName);
590 } else {
591 anyFieldsPopulated = true;
592 }
593 } else {
594 anyFieldsPopulated = true;
595 }
596 }
597
598
599
600 if (allFieldsPopulated) {
601 if (!unpopulatedFields.isEmpty()) {
602 throw new RuntimeException("The flag is set that indicates all fields are populated, but there " + "are fields present in the unpopulatedFields list. This should never happen, and indicates " + "that the logic in this method is broken.");
603 }
604 }
605
606 return new ForeignKeyFieldsPopulationState(allFieldsPopulated, anyFieldsPopulated, unpopulatedFields);
607 }
608
609
610
611
612
613 @Override
614 public Map<String, Class> listReferenceObjectFields(Class boClass) {
615
616 if (boClass == null) {
617 throw new IllegalArgumentException("Class specified in the parameter was null.");
618 }
619
620 Map<String, Class> references = new HashMap<String, Class>();
621 ClassDescriptor classDescriptor = getClassDescriptor(boClass);
622 Collection<ObjectReferenceDescriptor> referenceDescriptors = classDescriptor.getObjectReferenceDescriptors(true);
623
624 for (ObjectReferenceDescriptor referenceDescriptor : referenceDescriptors) {
625
626
627
628
629 String superReferenceDescriptor = referenceDescriptor.getAttributeName();
630 if (!SuperReferenceDescriptor.SUPER_FIELD_INTERNAL_NAME.equals(superReferenceDescriptor)) {
631 references.put(superReferenceDescriptor, referenceDescriptor.getItemClass());
632 }
633 }
634
635 return references;
636 }
637
638
639 @Override
640 public Map<String, Class> listCollectionObjectTypes(Class boClass) {
641 if (boClass == null) {
642 throw new IllegalArgumentException("Class specified in the parameter was null.");
643 }
644
645 Map<String, Class> references = new HashMap<String, Class>();
646 ClassDescriptor classDescriptor = null;
647 try {
648 classDescriptor = getClassDescriptor(boClass);
649 } catch (ClassNotPersistableException cnpe) {
650 return references;
651 }
652
653 Collection<CollectionDescriptor> collectionDescriptors = classDescriptor.getCollectionDescriptors(true);
654 for (CollectionDescriptor collectionDescriptor : collectionDescriptors) {
655 references.put(collectionDescriptor.getAttributeName(), collectionDescriptor.getItemClass());
656 }
657
658 return references;
659 }
660
661 @Override
662 public Map<String, Class> listCollectionObjectTypes(PersistableBusinessObject bo) {
663
664 if (bo == null) {
665 throw new IllegalArgumentException("BO specified in the parameter was null.");
666 }
667 if (!(bo instanceof PersistableBusinessObject)) {
668 throw new IllegalArgumentException("BO specified [" + bo.getClass().getName() + "] must be a class that " + "inherits from BusinessObject.");
669 }
670
671 return listCollectionObjectTypes(bo.getClass());
672 }
673
674
675
676
677 @Override
678 public Map<String, Class> listReferenceObjectFields(PersistableBusinessObject bo) {
679
680 if (bo == null) {
681 throw new IllegalArgumentException("BO specified in the parameter was null.");
682 }
683
684 return listReferenceObjectFields(bo.getClass());
685 }
686
687
688 @Override
689 public boolean isReferenceUpdatable(Class boClass, String referenceName) {
690 ClassDescriptor classDescriptor = getClassDescriptor(boClass);
691 ObjectReferenceDescriptor refDesc = classDescriptor.getObjectReferenceDescriptorByName(referenceName);
692 return refDesc.getCascadingStore() != ObjectReferenceDescriptor.CASCADE_NONE;
693 }
694
695
696 @Override
697 public boolean isCollectionUpdatable(Class boClass, String collectionName) {
698 ClassDescriptor cd = getClassDescriptor(boClass);
699 CollectionDescriptor collDesc = cd.getCollectionDescriptorByName(collectionName);
700 return collDesc.getCascadingStore() != ObjectReferenceDescriptor.CASCADE_NONE;
701 }
702
703
704 @Override
705 public boolean hasCollection(Class boClass, String collectionName) {
706 ClassDescriptor cd = getClassDescriptor(boClass);
707 return cd.getCollectionDescriptorByName(collectionName) != null;
708 }
709
710
711 @Override
712 public boolean hasReference(Class boClass, String referenceName) {
713 ClassDescriptor cd = getClassDescriptor(boClass);
714 return cd.getObjectReferenceDescriptorByName(referenceName) != null;
715 }
716
717
718
719
720
721
722
723 @Override
724 public String getTableName(Class<? extends PersistableBusinessObject> boClass) {
725 ClassDescriptor cd = getClassDescriptor(boClass);
726 return cd.getFullTableName();
727 }
728
729
730 }
731