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.Collections;
23 import java.util.Date;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.TreeMap;
29
30 import org.apache.commons.beanutils.PropertyUtils;
31 import org.apache.commons.lang.StringUtils;
32 import org.kuali.rice.core.api.config.property.ConfigurationService;
33 import org.kuali.rice.core.api.criteria.OrderByField;
34 import org.kuali.rice.core.api.criteria.OrderDirection;
35 import org.kuali.rice.core.api.criteria.QueryByCriteria;
36 import org.kuali.rice.core.api.criteria.QueryResults;
37 import org.kuali.rice.core.api.mo.common.Versioned;
38 import org.kuali.rice.core.api.search.SearchOperator;
39 import org.kuali.rice.core.api.uif.RemotableQuickFinder;
40 import org.kuali.rice.core.api.util.RiceKeyConstants;
41 import org.kuali.rice.core.framework.persistence.ojb.conversion.OjbCharBooleanConversion;
42 import org.kuali.rice.krad.bo.BusinessObject;
43 import org.kuali.rice.krad.bo.InactivatableFromTo;
44 import org.kuali.rice.krad.bo.PersistableBusinessObjectExtension;
45 import org.kuali.rice.krad.data.CompoundKey;
46 import org.kuali.rice.krad.data.DataObjectService;
47 import org.kuali.rice.krad.data.DataObjectWrapper;
48 import org.kuali.rice.krad.data.KradDataServiceLocator;
49 import org.kuali.rice.krad.data.PersistenceOption;
50 import org.kuali.rice.krad.data.metadata.DataObjectAttributeRelationship;
51 import org.kuali.rice.krad.data.metadata.DataObjectCollection;
52 import org.kuali.rice.krad.data.metadata.DataObjectMetadata;
53 import org.kuali.rice.krad.data.metadata.DataObjectRelationship;
54 import org.kuali.rice.krad.data.provider.annotation.ExtensionFor;
55 import org.kuali.rice.krad.datadictionary.DataDictionaryEntry;
56 import org.kuali.rice.krad.datadictionary.DataObjectEntry;
57 import org.kuali.rice.krad.datadictionary.PrimitiveAttributeDefinition;
58 import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
59 import org.kuali.rice.krad.datadictionary.SupportAttributeDefinition;
60 import org.kuali.rice.krad.document.Document;
61 import org.kuali.rice.krad.exception.ValidationException;
62 import org.kuali.rice.krad.lookup.LookupUtils;
63 import org.kuali.rice.krad.service.DataDictionaryService;
64 import org.kuali.rice.krad.service.DocumentAdHocService;
65 import org.kuali.rice.krad.service.KRADServiceLocator;
66 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
67 import org.kuali.rice.krad.service.KualiModuleService;
68 import org.kuali.rice.krad.service.LegacyDataAdapter;
69 import org.kuali.rice.krad.service.ModuleService;
70 import org.kuali.rice.krad.uif.service.ViewDictionaryService;
71 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
72 import org.kuali.rice.krad.util.ForeignKeyFieldsPopulationState;
73 import org.kuali.rice.krad.util.GlobalVariables;
74 import org.kuali.rice.krad.util.KRADConstants;
75 import org.kuali.rice.krad.util.KRADPropertyConstants;
76 import org.kuali.rice.krad.util.KRADUtils;
77 import org.kuali.rice.krad.util.LegacyUtils;
78 import org.springframework.beans.PropertyAccessorUtils;
79 import org.springframework.beans.factory.annotation.Required;
80 import org.springframework.dao.IncorrectResultSizeDataAccessException;
81
82
83
84
85 public class KRADLegacyDataAdapterImpl implements LegacyDataAdapter {
86 private DataObjectService dataObjectService;
87 private LookupCriteriaGenerator lookupCriteriaGenerator;
88
89 private ConfigurationService kualiConfigurationService;
90 private KualiModuleService kualiModuleService;
91 private DataDictionaryService dataDictionaryService;
92 private ViewDictionaryService viewDictionaryService;
93
94 @Override
95 public <T> T save(T dataObject) {
96 if (dataObject instanceof Collection) {
97 Collection<Object> newList = new ArrayList<Object>(((Collection) dataObject).size());
98 for (Object obj : (Collection<?>) dataObject) {
99 newList.add(save(obj));
100 }
101 return (T) newList;
102 } else {
103 return dataObjectService.save(dataObject);
104 }
105 }
106
107 @Override
108 public <T> T linkAndSave(T dataObject) {
109
110 return dataObjectService.save(dataObject, PersistenceOption.LINK_KEYS);
111 }
112
113 @Override
114 public <T> T saveDocument(T document) {
115 return dataObjectService.save(document, PersistenceOption.LINK_KEYS, PersistenceOption.FLUSH);
116 }
117
118 @Override
119 public <T> T findByPrimaryKey(Class<T> clazz, Map<String, ?> primaryKeys) {
120 return dataObjectService.find(clazz, new CompoundKey(primaryKeys));
121 }
122
123 @Override
124 public <T> T findBySinglePrimaryKey(Class<T> clazz, Object primaryKey) {
125 return dataObjectService.find(clazz, primaryKey);
126 }
127
128 @Override
129 public void delete(Object dataObject) {
130 if (dataObject instanceof Collection) {
131 for (Object dobj : (Collection) dataObject) {
132 delete(dobj);
133 }
134 } else {
135 dataObjectService.delete(dataObject);
136 }
137 }
138
139 @Override
140 public void deleteMatching(Class<?> type, Map<String, ?> fieldValues) {
141 dataObjectService.deleteMatching(type, QueryByCriteria.Builder.andAttributes(fieldValues).build());
142 }
143
144 @Override
145 public <T> T retrieve(T dataObject) {
146 Object id = null;
147 Map<String, Object> primaryKeyValues = dataObjectService.wrap(dataObject).getPrimaryKeyValues();
148 if (primaryKeyValues.isEmpty()) {
149 throw new IllegalArgumentException("Given data object has no primary key!");
150 }
151 if (primaryKeyValues.size() == 1) {
152 id = primaryKeyValues.values().iterator().next();
153 } else {
154 id = new CompoundKey(primaryKeyValues);
155 }
156 return dataObjectService.find((Class<T>) dataObject.getClass(), id);
157 }
158
159 @Override
160 public <T> Collection<T> findAll(Class<T> clazz) {
161
162 return findMatching(clazz, Collections.<String, Object>emptyMap());
163 }
164
165 @Override
166 public <T> Collection<T> findMatching(Class<T> clazz, Map<String, ?> fieldValues) {
167 QueryResults<T> result = dataObjectService.findMatching(clazz, QueryByCriteria.Builder.andAttributes(
168 fieldValues).build());
169 return result.getResults();
170 }
171
172 @Override
173 public <T> Collection<T> findMatchingOrderBy(Class<T> clazz, Map<String, ?> fieldValues, String sortField,
174 boolean sortAscending) {
175 OrderDirection direction = sortAscending ? OrderDirection.ASCENDING : OrderDirection.DESCENDING;
176 OrderByField orderBy = OrderByField.Builder.create(sortField, direction).build();
177 QueryResults<T> result = dataObjectService.findMatching(clazz, QueryByCriteria.Builder.andAttributes(
178 fieldValues).setOrderByFields(orderBy).build());
179 return result.getResults();
180 }
181
182 @Override
183 public Map<String, ?> getPrimaryKeyFieldValues(Object dataObject) {
184 return dataObjectService.wrap(dataObject).getPrimaryKeyValues();
185 }
186
187 @Override
188 public void retrieveNonKeyFields(Object persistableObject) {
189 List<DataObjectRelationship> relationships = dataObjectService.getMetadataRepository().getMetadata(
190 persistableObject.getClass()).getRelationships();
191 for (DataObjectRelationship relationship : relationships) {
192 retrieveReferenceObject(persistableObject, relationship.getName());
193 }
194 }
195
196 @Override
197 public void retrieveReferenceObject(Object persistableObject, String referenceObjectName) {
198 dataObjectService.wrap(persistableObject).fetchRelationship(referenceObjectName);
199 }
200
201 @Override
202 public void refreshAllNonUpdatingReferences(Object persistableObject) {
203 List<DataObjectRelationship> nonUpdateableRelationships = findNonUpdateableRelationships(persistableObject);
204 for (DataObjectRelationship relationship : nonUpdateableRelationships) {
205 retrieveReferenceObject(persistableObject, relationship.getName());
206 }
207 }
208
209 protected List<DataObjectRelationship> findNonUpdateableRelationships(Object persistableObject) {
210 List<DataObjectRelationship> nonUpdateableRelationships = new ArrayList<DataObjectRelationship>();
211 DataObjectMetadata dataObjectMetadata = dataObjectService.getMetadataRepository().
212 getMetadata(persistableObject.getClass());
213 if (dataObjectMetadata != null) {
214 List<DataObjectRelationship> relationships = dataObjectMetadata.getRelationships();
215 for (DataObjectRelationship relationship : relationships) {
216 if (!relationship.isSavedWithParent()) {
217 nonUpdateableRelationships.add(relationship);
218 }
219 }
220 }
221 return nonUpdateableRelationships;
222 }
223
224 @Override
225 public boolean isProxied(Object object) {
226
227 return false;
228 }
229
230 @Override
231 public Object resolveProxy(Object o) {
232
233 return o;
234 }
235
236
237
238 @Override
239 public <T> Collection<T> findCollectionBySearchHelper(Class<T> dataObjectClass, Map<String, String> formProperties,
240 boolean unbounded, boolean allPrimaryKeyValuesPresentAndNotWildcard, Integer searchResultsLimit) {
241 return performDataObjectServiceLookup(dataObjectClass, formProperties, unbounded,
242 allPrimaryKeyValuesPresentAndNotWildcard, searchResultsLimit);
243 }
244
245 @Override
246 public <T> Collection<T> findCollectionBySearchHelper(Class<T> dataObjectClass, Map<String, String> formProperties,
247 List<String> wildcardAsLiteralPropertyNames, boolean unbounded,
248 boolean allPrimaryKeyValuesPresentAndNotWildcard, Integer searchResultsLimit) {
249 return performDataObjectServiceLookup(dataObjectClass, formProperties, wildcardAsLiteralPropertyNames,
250 unbounded, allPrimaryKeyValuesPresentAndNotWildcard, searchResultsLimit);
251 }
252
253
254
255
256
257
258
259
260
261
262
263 protected <T> Collection<T> performDataObjectServiceLookup(Class<T> dataObjectClass,
264 Map<String, String> formProperties, boolean unbounded, boolean allPrimaryKeyValuesPresentAndNotWildcard,
265 Integer searchResultsLimit) {
266 if (!unbounded && searchResultsLimit == null) {
267
268
269 searchResultsLimit = org.kuali.rice.kns.lookup.LookupUtils.getSearchResultsLimit(dataObjectClass);
270 }
271 QueryByCriteria.Builder query = lookupCriteriaGenerator.generateCriteria(dataObjectClass, formProperties,
272 allPrimaryKeyValuesPresentAndNotWildcard);
273 if (!unbounded && searchResultsLimit != null) {
274 query.setMaxResults(searchResultsLimit);
275 }
276
277 Collection<T> results = dataObjectService.findMatching(dataObjectClass, query.build()).getResults();
278 return filterCurrentDataObjects(dataObjectClass, results, formProperties);
279 }
280
281
282
283
284
285
286
287
288
289
290
291
292 protected <T> Collection<T> performDataObjectServiceLookup(Class<T> dataObjectClass,
293 Map<String, String> formProperties, List<String> wildcardAsLiteralPropertyNames, boolean unbounded,
294 boolean allPrimaryKeyValuesPresentAndNotWildcard, Integer searchResultsLimit) {
295 if (!unbounded && searchResultsLimit == null) {
296
297
298 searchResultsLimit = org.kuali.rice.kns.lookup.LookupUtils.getSearchResultsLimit(dataObjectClass);
299 }
300
301 QueryByCriteria.Builder query = lookupCriteriaGenerator.generateCriteria(dataObjectClass, formProperties,
302 wildcardAsLiteralPropertyNames, allPrimaryKeyValuesPresentAndNotWildcard);
303 if (!unbounded && searchResultsLimit != null) {
304 query.setMaxResults(searchResultsLimit);
305 }
306
307 Collection<T> results = dataObjectService.findMatching(dataObjectClass, query.build()).getResults();
308 return filterCurrentDataObjects(dataObjectClass, results, formProperties);
309 }
310
311 protected <T> Collection<T> filterCurrentDataObjects(Class<T> dataObjectClass, Collection<T> unfiltered,
312 Map<String, String> formProps) {
313 if (InactivatableFromTo.class.isAssignableFrom(dataObjectClass)) {
314 Boolean currentSpecifier = lookupCriteriaCurrentSpecifier(formProps);
315 if (currentSpecifier != null) {
316 List<InactivatableFromTo> onlyCurrent =
317 KRADServiceLocator.getInactivateableFromToService().filterOutNonCurrent(new ArrayList(
318 unfiltered), new Date(LookupUtils.getActiveDateTimestampForCriteria(formProps)
319 .getTime()));
320 if (currentSpecifier) {
321 return (Collection<T>) onlyCurrent;
322 } else {
323 unfiltered.removeAll(onlyCurrent);
324 return unfiltered;
325 }
326 }
327 }
328 return unfiltered;
329 }
330
331 protected Boolean lookupCriteriaCurrentSpecifier(Map<String, String> formProps) {
332 String value = formProps.get(KRADPropertyConstants.CURRENT);
333 if (StringUtils.isNotBlank(value)) {
334
335 String currentBooleanStr = (String) new OjbCharBooleanConversion().javaToSql(value);
336 if (OjbCharBooleanConversion.DATABASE_BOOLEAN_TRUE_STRING_REPRESENTATION.equals(currentBooleanStr)) {
337 return Boolean.TRUE;
338 } else if (OjbCharBooleanConversion.DATABASE_BOOLEAN_FALSE_STRING_REPRESENTATION.equals(
339 currentBooleanStr)) {
340 return Boolean.FALSE;
341 }
342 }
343 return null;
344 }
345
346 @Override
347 public <T> T findObjectBySearch(Class<T> type, Map<String, String> formProps) {
348
349
350
351 QueryByCriteria.Builder queryByCriteria = lookupCriteriaGenerator.createObjectCriteriaFromMap(type, formProps);
352 List<T> results = dataObjectService.findMatching(type, queryByCriteria.build()).getResults();
353 if (results.isEmpty()) {
354 return null;
355 }
356 if (results.size() != 1) {
357
358
359 throw new IncorrectResultSizeDataAccessException("Incorrect number of results returned when finding object",
360 1, results.size());
361 }
362 return results.get(0);
363 }
364
365
366
367
368
369
370
371
372 @Override
373 public boolean allPrimaryKeyValuesPresentAndNotWildcard(Class<?> boClass, Map<String, String> formProps) {
374 List<String> pkFields = listPrimaryKeyFieldNames(boClass);
375 Iterator<String> pkIter = pkFields.iterator();
376 boolean returnVal = true;
377 while (returnVal && pkIter.hasNext()) {
378 String pkName = pkIter.next();
379 String pkValue = formProps.get(pkName);
380
381 if (StringUtils.isBlank(pkValue)) {
382 returnVal = false;
383 } else {
384 for (SearchOperator op : SearchOperator.QUERY_CHARACTERS) {
385 if (pkValue.contains(op.op())) {
386 returnVal = false;
387 break;
388 }
389 }
390 }
391 }
392 return returnVal;
393 }
394
395
396
397
398
399
400
401 @Override
402 public List<String> listPrimaryKeyFieldNames(Class<?> type) {
403 List<String> keys = Collections.emptyList();
404 if (dataObjectService.getMetadataRepository().contains(type)) {
405 keys = dataObjectService.getMetadataRepository().getMetadata(type).getPrimaryKeyAttributeNames();
406 } else {
407
408 DataObjectEntry dataObjectEntry = dataDictionaryService.getDataDictionary().getDataObjectEntry(
409 type.getName());
410 if (dataObjectEntry != null) {
411 List<String> pks = dataObjectEntry.getPrimaryKeys();
412 if (pks != null) {
413 keys = pks;
414 }
415 } else {
416 ModuleService responsibleModuleService = kualiModuleService.getResponsibleModuleService(type);
417 if (responsibleModuleService != null && responsibleModuleService.isExternalizable(type)) {
418 keys = responsibleModuleService.listPrimaryKeyFieldNames(type);
419 }
420 }
421 }
422 return keys;
423 }
424
425
426
427
428
429
430
431
432
433
434
435
436
437 protected List<String> listPrimaryKeyFieldNamesConsultingAllServices(Class<?> type) {
438 List<String> keys = new ArrayList<String>();
439 if (dataObjectService.getMetadataRepository().contains(type)) {
440 keys = dataObjectService.getMetadataRepository().getMetadata(type).getPrimaryKeyAttributeNames();
441 }
442 return keys;
443 }
444
445 @Override
446 public Class<?> determineCollectionObjectType(Class<?> containingType, String collectionPropertyName) {
447 final Class<?> collectionObjectType;
448 if (dataObjectService.getMetadataRepository().contains(containingType)) {
449 DataObjectMetadata metadata = dataObjectService.getMetadataRepository().getMetadata(containingType);
450 DataObjectCollection collection = metadata.getCollection(collectionPropertyName);
451 if (collection == null) {
452 throw new IllegalArgumentException(
453 "Failed to locate a collection property with the given name: " + collectionPropertyName);
454 }
455 collectionObjectType = collection.getRelatedType();
456 } else {
457 throw new IllegalArgumentException(
458 "Given containing class is not a valid data object, no metadata could be located for "
459 + containingType.getName());
460 }
461 return collectionObjectType;
462
463 }
464
465 @Override
466 public boolean hasReference(Class<?> boClass, String referenceName) {
467 throw new UnsupportedOperationException("hasReference not valid for KRAD data operation");
468 }
469
470 @Override
471 public boolean hasCollection(Class<?> boClass, String collectionName) {
472 throw new UnsupportedOperationException("hasCollection not valid for KRAD data operation");
473 }
474
475 @Override
476 public boolean isExtensionAttribute(Class<?> boClass, String attributePropertyName, Class<?> propertyType) {
477 DataObjectMetadata metadata = dataObjectService.getMetadataRepository().getMetadata(boClass);
478 if (metadata != null) {
479 DataObjectRelationship relationship = metadata.getRelationship(attributePropertyName);
480 if (relationship != null) {
481 Class<?> relatedType = relationship.getRelatedType();
482
483
484 ExtensionFor annotation = relatedType.getAnnotation(ExtensionFor.class);
485 if (annotation != null) {
486 return annotation.value().equals(boClass);
487 }
488 }
489 }
490 return false;
491 }
492
493 @Override
494 public Class<?> getExtensionAttributeClass(Class<?> boClass, String attributePropertyName) {
495 DataObjectMetadata metadata = dataObjectService.getMetadataRepository().getMetadata(boClass);
496 if (metadata != null) {
497 DataObjectRelationship relationship = metadata.getRelationship(attributePropertyName);
498 if (relationship != null) {
499 return relationship.getRelatedType();
500 }
501 }
502 return null;
503 }
504
505 @Override
506 public Map<String, ?> getPrimaryKeyFieldValuesDOMDS(Object dataObject) {
507 return dataObjectService.wrap(dataObject).getPrimaryKeyValues();
508 }
509
510 @Override
511 public boolean equalsByPrimaryKeys(Object do1, Object do2) {
512 return dataObjectService.wrap(do1).equalsByPrimaryKey(do2);
513 }
514
515
516
517
518
519
520 @Override
521 public void materializeAllSubObjects(Object object) {
522 DataObjectWrapper<?> wrappedObject = dataObjectService.wrap(object);
523
524
525 wrappedObject.materializeReferencedObjectsToDepth(3);
526 }
527
528 @Override
529
530
531
532 public Class<?> getPropertyType(Object object, String propertyName) {
533 DataObjectWrapper<?> wrappedObject = dataObjectService.wrap(object);
534 if (PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName)) {
535 return wrappedObject.getPropertyTypeNullSafe(wrappedObject.getWrappedClass(), propertyName);
536 }
537 return wrappedObject.getPropertyType(propertyName);
538 }
539
540 @Override
541 public Object getExtension(
542 Class<?> businessObjectClass) throws InstantiationException, IllegalAccessException {
543 DataObjectMetadata metadata = dataObjectService.getMetadataRepository().getMetadata(businessObjectClass);
544 DataObjectRelationship extensionRelationship = metadata.getRelationship("extension");
545 if (extensionRelationship != null) {
546 Class<?> extensionType = extensionRelationship.getRelatedType();
547 return extensionType.newInstance();
548 }
549 return null;
550 }
551
552 @Override
553 public void refreshReferenceObject(Object businessObject, String referenceObjectName) {
554 dataObjectService.wrap(businessObject).fetchRelationship(referenceObjectName);
555 }
556
557 @Override
558 public boolean isLockable(Object object) {
559 return isPersistable(object.getClass());
560 }
561
562 @Override
563 public void verifyVersionNumber(Object dataObject) {
564 DataObjectMetadata metadata = dataObjectService.getMetadataRepository().getMetadata(dataObject.getClass());
565 if (metadata == null) {
566 return;
567 }
568
569 if (metadata.isSupportsOptimisticLocking()) {
570 if (dataObject instanceof Versioned) {
571 Map<String, ?> keyPropertyValues = dataObjectService.wrap(dataObject).getPrimaryKeyValues();
572 CompoundKey key = new CompoundKey(keyPropertyValues);
573 Object persistableDataObject = null;
574 if (!key.hasNullKeyValues()) {
575 persistableDataObject = dataObjectService.find(dataObject.getClass(), key);
576 }
577
578 if (persistableDataObject != null) {
579 Long databaseVersionNumber = ((Versioned) persistableDataObject).getVersionNumber();
580 Long documentVersionNumber = ((Versioned) dataObject).getVersionNumber();
581 if (databaseVersionNumber != null && !(databaseVersionNumber.equals(documentVersionNumber))) {
582 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS,
583 RiceKeyConstants.ERROR_VERSION_MISMATCH);
584 throw new ValidationException(
585 "Version mismatch between the local business object and the database business object");
586 }
587 }
588 }
589 }
590 }
591
592 @Override
593 public RemotableQuickFinder.Builder createQuickFinder(Class<?> containingClass, String attributeName) {
594 return createQuickFinderNew(containingClass, attributeName);
595 }
596
597
598
599
600 protected RemotableQuickFinder.Builder createQuickFinderNew(Class<?> containingClass, String attributeName) {
601 if (dataObjectService.getMetadataRepository().contains(containingClass)) {
602
603 String lookupClassName = null;
604 Map<String, String> fieldConversions = new HashMap<String, String>();
605 Map<String, String> lookupParameters = new HashMap<String, String>();
606
607 DataObjectMetadata metadata = dataObjectService.getMetadataRepository().getMetadata(containingClass);
608 DataObjectRelationship relationship = metadata.getRelationshipByLastAttributeInRelationship(attributeName);
609 if (relationship != null) {
610 DataObjectMetadata lookupClassMetadata = dataObjectService.getMetadataRepository().getMetadata(
611 relationship.getRelatedType());
612 lookupClassName = lookupClassMetadata.getClass().getName();
613 for (DataObjectAttributeRelationship attributeRelationship : relationship.getAttributeRelationships()) {
614
615
616
617
618 fieldConversions.put(attributeRelationship.getChildAttributeName(),
619 attributeRelationship.getParentAttributeName());
620
621
622
623 lookupParameters.put(attributeRelationship.getParentAttributeName(),
624 attributeRelationship.getChildAttributeName());
625 }
626
627
628
629
630
631 if (lookupClassMetadata.hasDistinctBusinessKey()) {
632 lookupParameters.clear();
633 for (String businessKeyAttributeName : lookupClassMetadata.getBusinessKeyAttributeNames()) {
634 lookupParameters.put(relationship.getName() + "." + businessKeyAttributeName,
635 businessKeyAttributeName);
636 }
637 }
638 } else {
639
640 String primaryDisplayAttributeName = metadata.getPrimaryDisplayAttributeName();
641 if (StringUtils.equals(primaryDisplayAttributeName, attributeName)) {
642 lookupClassName = containingClass.getName();
643 List<String> primaryKeyAttributes = metadata.getPrimaryKeyAttributeNames();
644 for (String primaryKeyAttribute : primaryKeyAttributes) {
645 fieldConversions.put(primaryKeyAttribute, primaryKeyAttribute);
646 if (!StringUtils.equals(primaryKeyAttribute, attributeName)) {
647 lookupParameters.put(primaryKeyAttribute, primaryKeyAttribute);
648 }
649 }
650 }
651 }
652
653 if (StringUtils.isNotBlank(lookupClassName)) {
654 String baseUrl = kualiConfigurationService.getPropertyValueAsString(KRADConstants.KRAD_LOOKUP_URL_KEY);
655 RemotableQuickFinder.Builder builder = RemotableQuickFinder.Builder.create(baseUrl, lookupClassName);
656 builder.setLookupParameters(lookupParameters);
657 builder.setFieldConversions(fieldConversions);
658 return builder;
659 }
660
661 }
662 return null;
663 }
664
665 @Override
666 public boolean isReferenceUpdatable(Class<?> type, String referenceName) {
667 if (dataObjectService.getMetadataRepository().contains(type)) {
668 DataObjectRelationship relationship = dataObjectService.getMetadataRepository().getMetadata(type)
669 .getRelationship(referenceName);
670 if (relationship != null) {
671 return relationship.isSavedWithParent();
672 }
673 }
674 return false;
675 }
676
677 @SuppressWarnings("rawtypes")
678 @Override
679 public Map<String, Class> listReferenceObjectFields(Class<?> type) {
680 Map<String, Class> referenceNameToTypeMap = new HashMap<String, Class>();
681 if (dataObjectService.getMetadataRepository().contains(type)) {
682 List<DataObjectRelationship> relationships = dataObjectService.getMetadataRepository().getMetadata(type)
683 .getRelationships();
684 for (DataObjectRelationship rel : relationships) {
685 referenceNameToTypeMap.put(rel.getName(), rel.getRelatedType());
686 }
687 }
688 return referenceNameToTypeMap;
689 }
690
691 @Override
692 public boolean isCollectionUpdatable(Class<?> type, String collectionName) {
693 if (dataObjectService.getMetadataRepository().contains(type)) {
694 DataObjectCollection collection = dataObjectService.getMetadataRepository().getMetadata(type).getCollection(
695 collectionName);
696 if (collection != null) {
697 return collection.isSavedWithParent();
698 }
699 }
700 return false;
701 }
702
703 @Override
704 public Map<String, Class> listCollectionObjectTypes(Class<?> type) {
705 Map<String, Class> collectionNameToTypeMap = new HashMap<String, Class>();
706 if (dataObjectService.getMetadataRepository().contains(type)) {
707 List<DataObjectCollection> collections = dataObjectService.getMetadataRepository().getMetadata(type)
708 .getCollections();
709 for (DataObjectCollection coll : collections) {
710 collectionNameToTypeMap.put(coll.getName(), coll.getRelatedType());
711 }
712 }
713 return collectionNameToTypeMap;
714 }
715
716 @Override
717 public Object getReferenceIfExists(Object bo, String referenceName) {
718
719 DataObjectWrapper<Object> dataObjectWrapper = dataObjectService.wrap(bo);
720 dataObjectWrapper.fetchRelationship(referenceName);
721 return dataObjectWrapper.getPropertyValueNullSafe(referenceName);
722 }
723
724 @Override
725 public boolean allForeignKeyValuesPopulatedForReference(Object bo, String referenceName) {
726 Map<String, String> fkReferences = getForeignKeysForReference(bo.getClass(), referenceName);
727 if (fkReferences.size() > 0) {
728 DataObjectWrapper<Object> dataObjectWrapper = dataObjectService.wrap(bo);
729
730 for (String fkFieldName : fkReferences.keySet()) {
731 Object fkFieldValue = dataObjectWrapper.getForeignKeyAttributeValue(fkFieldName);
732 if (fkFieldValue == null) {
733 return false;
734 } else if (fkFieldValue instanceof CompoundKey) {
735 return !((CompoundKey) fkFieldValue).hasNullKeyValues();
736 } else if (String.class.isAssignableFrom(fkFieldValue.getClass())) {
737 if (StringUtils.isBlank((String) fkFieldValue)) {
738 return false;
739 }
740 }
741 }
742 }
743
744 return true;
745 }
746
747
748
749
750
751
752
753
754 @Override
755 public RelationshipDefinition getDictionaryRelationship(Class<?> c, String attributeName) {
756 DataDictionaryEntry entryBase =
757 KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDictionaryObjectEntry(
758 c.getName());
759 if (entryBase == null) {
760 return null;
761 }
762
763 RelationshipDefinition relationship = null;
764
765 List<RelationshipDefinition> ddRelationships = entryBase.getRelationships();
766
767 int minKeys = Integer.MAX_VALUE;
768 for (RelationshipDefinition def : ddRelationships) {
769
770 if (def.getPrimitiveAttributes().size() == 1) {
771 for (PrimitiveAttributeDefinition primitive : def.getPrimitiveAttributes()) {
772 if (primitive.getSourceName().equals(attributeName) || def.getObjectAttributeName().equals(
773 attributeName)) {
774 relationship = def;
775 minKeys = 1;
776 break;
777 }
778 }
779 } else if (def.getPrimitiveAttributes().size() < minKeys) {
780 for (PrimitiveAttributeDefinition primitive : def.getPrimitiveAttributes()) {
781 if (primitive.getSourceName().equals(attributeName) || def.getObjectAttributeName().equals(
782 attributeName)) {
783 relationship = def;
784 minKeys = def.getPrimitiveAttributes().size();
785 break;
786 }
787 }
788 }
789 }
790
791
792 if (relationship == null) {
793 for (RelationshipDefinition def : ddRelationships) {
794 if (def.hasIdentifier()) {
795 if (def.getIdentifier().getSourceName().equals(attributeName)) {
796 relationship = def;
797 }
798 }
799 }
800 }
801
802 return relationship;
803 }
804
805
806
807
808 @Override
809 public String getTitleAttribute(Class<?> dataObjectClass) {
810 String titleAttribute = null;
811 DataObjectEntry entry = getDataObjectEntry(dataObjectClass);
812 if (entry != null) {
813 titleAttribute = entry.getTitleAttribute();
814 }
815 return titleAttribute;
816 }
817
818
819
820
821
822
823
824 protected DataObjectEntry getDataObjectEntry(Class<?> dataObjectClass) {
825 if (dataObjectClass == null) {
826 throw new IllegalArgumentException("invalid (null) dataObjectClass");
827 }
828
829 DataObjectEntry entry = dataDictionaryService.getDataDictionary().getDataObjectEntry(dataObjectClass.getName());
830
831 return entry;
832 }
833
834
835
836
837 @Override
838 public boolean areNotesSupported(Class<?> dataObjectClass) {
839 boolean hasNotesSupport = false;
840
841 DataObjectEntry entry = getDataObjectEntry(dataObjectClass);
842 if (entry != null) {
843 hasNotesSupport = entry.isBoNotesEnabled();
844 }
845
846 return hasNotesSupport;
847 }
848
849
850
851
852
853
854
855
856 public Map<String, ?> getPrimaryKeyFieldValues(Object dataObject, boolean sortFieldNames) {
857 Map<String, Object> keyFieldValues = (Map<String, Object>) getPrimaryKeyFieldValues(dataObject);
858 if (sortFieldNames) {
859 Map<String, Object> sortedKeyFieldValues = new TreeMap<String, Object>();
860 sortedKeyFieldValues.putAll(keyFieldValues);
861 return sortedKeyFieldValues;
862 }
863 return keyFieldValues;
864 }
865
866
867
868
869 @Override
870 public String getDataObjectIdentifierString(Object dataObject) {
871 String identifierString = "";
872
873 if (dataObject == null) {
874 identifierString = "Null";
875 return identifierString;
876 }
877
878 Class<?> dataObjectClass = dataObject.getClass();
879
880 Map<String, ?> primaryKeyFieldValues = getPrimaryKeyFieldValues(dataObject, true);
881 for (Map.Entry<String, ?> primaryKeyValue : primaryKeyFieldValues.entrySet()) {
882 if (primaryKeyValue.getValue() == null) {
883 identifierString += "Null";
884 } else {
885 identifierString += primaryKeyValue.getValue();
886 }
887 identifierString += ":";
888 }
889 return StringUtils.removeEnd(identifierString, ":");
890 }
891
892 @Override
893 public Class<?> getInquiryObjectClassIfNotTitle(Object dataObject, String propertyName) {
894 DataObjectMetadata objectMetadata =
895 KRADServiceLocator.getDataObjectService().getMetadataRepository().getMetadata(dataObject.getClass());
896 if (objectMetadata != null) {
897 org.kuali.rice.krad.data.metadata.DataObjectRelationship dataObjectRelationship =
898 objectMetadata.getRelationship(propertyName);
899 if (dataObjectRelationship != null) {
900 return dataObjectRelationship.getRelatedType();
901 }
902 }
903 return null;
904 }
905
906 @Override
907 public Map<String, String> getInquiryParameters(Object dataObject, List<String> keys, String propertyName) {
908 Map<String, String> inquiryParameters = new HashMap<String, String>();
909 org.kuali.rice.krad.data.metadata.DataObjectRelationship dataObjectRelationship = null;
910
911 DataObjectMetadata objectMetadata =
912 KRADServiceLocator.getDataObjectService().getMetadataRepository().getMetadata(dataObject.getClass());
913
914 if (objectMetadata != null) {
915 dataObjectRelationship = objectMetadata.getRelationshipByLastAttributeInRelationship(propertyName);
916 }
917
918 for (String keyName : keys) {
919 String keyConversion = keyName;
920 if (dataObjectRelationship != null) {
921 keyConversion = dataObjectRelationship.getParentAttributeNameRelatedToChildAttributeName(keyName);
922 } else if (PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName)) {
923 String nestedAttributePrefix = KRADUtils.getNestedAttributePrefix(propertyName);
924 keyConversion = nestedAttributePrefix + "." + keyName;
925 }
926 inquiryParameters.put(keyConversion, keyName);
927 }
928 return inquiryParameters;
929 }
930
931 @Override
932 public boolean hasLocalLookup(Class<?> dataObjectClass) {
933 return viewDictionaryService.isLookupable(dataObjectClass);
934 }
935
936 @Override
937 public boolean hasLocalInquiry(Class<?> dataObjectClass) {
938 return viewDictionaryService.isInquirable(dataObjectClass);
939 }
940
941 @Override
942 public org.kuali.rice.krad.bo.DataObjectRelationship getDataObjectRelationship(Object dataObject,
943 Class<?> dataObjectClass, String attributeName, String attributePrefix, boolean keysOnly,
944 boolean supportsLookup, boolean supportsInquiry) {
945 RelationshipDefinition ddReference = getDictionaryRelationship(dataObjectClass, attributeName);
946
947 org.kuali.rice.krad.bo.DataObjectRelationship relationship = null;
948 DataObjectAttributeRelationship rel = null;
949 if (PropertyAccessorUtils.isNestedOrIndexedProperty(attributeName)) {
950 if (ddReference != null) {
951 if (classHasSupportedFeatures(ddReference.getTargetClass(), supportsLookup, supportsInquiry)) {
952 relationship = populateRelationshipFromDictionaryReference(dataObjectClass, ddReference,
953 attributePrefix, keysOnly);
954
955 return relationship;
956 }
957 }
958
959 if (dataObject == null) {
960 try {
961 dataObject = KRADUtils.createNewObjectFromClass(dataObjectClass);
962 } catch (RuntimeException e) {
963
964 return null;
965 }
966 }
967
968
969 int nextObjectIndex = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(attributeName);
970 if (nextObjectIndex == StringUtils.INDEX_NOT_FOUND) {
971 nextObjectIndex = attributeName.length();
972 }
973 String localPrefix = StringUtils.substring(attributeName, 0, nextObjectIndex);
974 String localAttributeName = StringUtils.substring(attributeName, nextObjectIndex + 1);
975 Object nestedObject = ObjectPropertyUtils.getPropertyValue(dataObject, localPrefix);
976 Class<?> nestedClass = null;
977 if (nestedObject == null) {
978 nestedClass = ObjectPropertyUtils.getPropertyType(dataObject, localPrefix);
979 } else {
980 nestedClass = nestedObject.getClass();
981 }
982
983 String fullPrefix = localPrefix;
984 if (StringUtils.isNotBlank(attributePrefix)) {
985 fullPrefix = attributePrefix + "." + localPrefix;
986 }
987
988 relationship = getDataObjectRelationship(nestedObject, nestedClass, localAttributeName, fullPrefix,
989 keysOnly, supportsLookup, supportsInquiry);
990
991 return relationship;
992 }
993
994
995 int maxSize = Integer.MAX_VALUE;
996
997 if (isPersistable(dataObjectClass)) {
998 DataObjectMetadata metadata = dataObjectService.getMetadataRepository().getMetadata(dataObjectClass);
999 DataObjectRelationship dataObjectRelationship = metadata.getRelationship(attributeName);
1000
1001 if (dataObjectRelationship != null) {
1002 List<DataObjectAttributeRelationship> attributeRelationships =
1003 dataObjectRelationship.getAttributeRelationships();
1004 for (DataObjectAttributeRelationship dataObjectAttributeRelationship : attributeRelationships) {
1005 if (classHasSupportedFeatures(dataObjectRelationship.getRelatedType(), supportsLookup,
1006 supportsInquiry)) {
1007 maxSize = attributeRelationships.size();
1008 relationship = transformToDeprecatedDataObjectRelationship(dataObjectClass, attributeName,
1009 attributePrefix, dataObjectRelationship.getRelatedType(),
1010 dataObjectAttributeRelationship);
1011
1012 break;
1013 }
1014 }
1015 }
1016
1017 } else {
1018 ModuleService moduleService = kualiModuleService.getResponsibleModuleService(dataObjectClass);
1019 if (moduleService != null && moduleService.isExternalizable(dataObjectClass)) {
1020 relationship = getRelationshipMetadata(dataObjectClass, attributeName, attributePrefix);
1021 if ((relationship != null) && classHasSupportedFeatures(relationship.getRelatedClass(), supportsLookup,
1022 supportsInquiry)) {
1023 return relationship;
1024 } else {
1025 return null;
1026 }
1027 }
1028 }
1029
1030 if (ddReference != null && ddReference.getPrimitiveAttributes().size() < maxSize) {
1031 if (classHasSupportedFeatures(ddReference.getTargetClass(), supportsLookup, supportsInquiry)) {
1032 relationship = populateRelationshipFromDictionaryReference(dataObjectClass, ddReference, null,
1033 keysOnly);
1034 }
1035 }
1036 return relationship;
1037 }
1038
1039 protected org.kuali.rice.krad.bo.DataObjectRelationship transformToDeprecatedDataObjectRelationship(
1040 Class<?> dataObjectClass, String attributeName, String attributePrefix, Class<?> relatedObjectClass,
1041 DataObjectAttributeRelationship relationship) {
1042 org.kuali.rice.krad.bo.DataObjectRelationship rel = new org.kuali.rice.krad.bo.DataObjectRelationship(
1043 dataObjectClass, attributeName, relatedObjectClass);
1044 if (StringUtils.isBlank(attributePrefix)) {
1045 rel.getParentToChildReferences().put(relationship.getParentAttributeName(),
1046 relationship.getChildAttributeName());
1047 } else {
1048 rel.getParentToChildReferences().put(attributePrefix + "." + relationship.getParentAttributeName(),
1049 relationship.getChildAttributeName());
1050 }
1051
1052 return rel;
1053 }
1054
1055 protected org.kuali.rice.krad.bo.DataObjectRelationship populateRelationshipFromDictionaryReference(
1056 Class<?> dataObjectClass, RelationshipDefinition ddReference, String attributePrefix, boolean keysOnly) {
1057 org.kuali.rice.krad.bo.DataObjectRelationship relationship = new org.kuali.rice.krad.bo.DataObjectRelationship(
1058 dataObjectClass, ddReference.getObjectAttributeName(), ddReference.getTargetClass());
1059
1060 for (PrimitiveAttributeDefinition def : ddReference.getPrimitiveAttributes()) {
1061 if (StringUtils.isNotBlank(attributePrefix)) {
1062 relationship.getParentToChildReferences().put(attributePrefix + "." + def.getSourceName(),
1063 def.getTargetName());
1064 } else {
1065 relationship.getParentToChildReferences().put(def.getSourceName(), def.getTargetName());
1066 }
1067 }
1068
1069 if (!keysOnly) {
1070 for (SupportAttributeDefinition def : ddReference.getSupportAttributes()) {
1071 if (StringUtils.isNotBlank(attributePrefix)) {
1072 relationship.getParentToChildReferences().put(attributePrefix + "." + def.getSourceName(),
1073 def.getTargetName());
1074 if (def.isIdentifier()) {
1075 relationship.setUserVisibleIdentifierKey(attributePrefix + "." + def.getSourceName());
1076 }
1077 } else {
1078 relationship.getParentToChildReferences().put(def.getSourceName(), def.getTargetName());
1079 if (def.isIdentifier()) {
1080 relationship.setUserVisibleIdentifierKey(def.getSourceName());
1081 }
1082 }
1083 }
1084 }
1085
1086 return relationship;
1087 }
1088
1089 @Override
1090 public boolean isPersistable(Class<?> dataObjectClass) {
1091 return dataObjectService.getMetadataRepository().contains(dataObjectClass);
1092 }
1093
1094 protected org.kuali.rice.krad.bo.DataObjectRelationship getRelationshipMetadata(Class<?> dataObjectClass,
1095 String attributeName, String attributePrefix) {
1096
1097 RelationshipDefinition relationshipDefinition = getDictionaryRelationship(dataObjectClass, attributeName);
1098 if (relationshipDefinition == null) {
1099 return null;
1100 }
1101
1102 org.kuali.rice.krad.bo.DataObjectRelationship dataObjectRelationship =
1103 new org.kuali.rice.krad.bo.DataObjectRelationship(relationshipDefinition.getSourceClass(),
1104 relationshipDefinition.getObjectAttributeName(), relationshipDefinition.getTargetClass());
1105
1106 if (!StringUtils.isEmpty(attributePrefix)) {
1107 attributePrefix += ".";
1108 }
1109
1110 List<PrimitiveAttributeDefinition> primitives = relationshipDefinition.getPrimitiveAttributes();
1111 for (PrimitiveAttributeDefinition primitiveAttributeDefinition : primitives) {
1112 dataObjectRelationship.getParentToChildReferences().put(
1113 attributePrefix + primitiveAttributeDefinition.getSourceName(),
1114 primitiveAttributeDefinition.getTargetName());
1115 }
1116
1117 return dataObjectRelationship;
1118 }
1119
1120 protected boolean classHasSupportedFeatures(Class relationshipClass, boolean supportsLookup,
1121 boolean supportsInquiry) {
1122 boolean hasSupportedFeatures = true;
1123 if (supportsLookup && !getViewDictionaryService().isLookupable(relationshipClass)) {
1124 hasSupportedFeatures = false;
1125 }
1126 if (supportsInquiry && !getViewDictionaryService().isInquirable(relationshipClass)) {
1127 hasSupportedFeatures = false;
1128 }
1129
1130 return hasSupportedFeatures;
1131 }
1132
1133 @Override
1134 public ForeignKeyFieldsPopulationState getForeignKeyFieldsPopulationState(Object dataObject, String referenceName) {
1135 DataObjectWrapper<Object> dataObjectWrapper = dataObjectService.wrap(dataObject);
1136 return new ForeignKeyFieldsPopulationState(dataObjectWrapper.areAllPrimaryKeyAttributesPopulated(),
1137 dataObjectWrapper.areAnyPrimaryKeyAttributesPopulated(),
1138 dataObjectWrapper.getUnpopulatedPrimaryKeyAttributeNames());
1139 }
1140
1141 @Override
1142 public Map<String, String> getForeignKeysForReference(Class<?> clazz, String attributeName) {
1143 if (dataObjectService.getMetadataRepository().contains(clazz)) {
1144 DataObjectRelationship relationship = dataObjectService.getMetadataRepository().getMetadata(clazz)
1145 .getRelationship(attributeName);
1146 List<DataObjectAttributeRelationship> attributeRelationships = relationship.getAttributeRelationships();
1147 Map<String, String> parentChildKeyRelationships = new HashMap<String, String>(
1148 attributeRelationships.size());
1149 for (DataObjectAttributeRelationship doar : attributeRelationships) {
1150 parentChildKeyRelationships.put(doar.getParentAttributeName(), doar.getChildAttributeName());
1151 }
1152 return parentChildKeyRelationships;
1153 }
1154 return Collections.emptyMap();
1155 }
1156
1157 @Override
1158 public void setObjectPropertyDeep(Object bo, String propertyName, Class type,
1159 Object propertyValue) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
1160 DataObjectWrapper<Object> dataObjectWrapper = dataObjectService.wrap(bo);
1161
1162 if (KRADUtils.isNull(bo) || !PropertyUtils.isReadable(bo, propertyName) || (propertyValue != null
1163 && propertyValue.equals(dataObjectWrapper.getPropertyValueNullSafe(propertyName))) || (type != null
1164 && !type.equals(KRADUtils.easyGetPropertyType(bo, propertyName)))) {
1165 return;
1166 }
1167
1168 KRADUtils.setObjectProperty(bo, propertyName, type, propertyValue);
1169
1170
1171 PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(bo.getClass());
1172 for (int i = 0; i < propertyDescriptors.length; i++) {
1173
1174 PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
1175
1176
1177 if (propertyDescriptor.getPropertyType() != null && (BusinessObject.class).isAssignableFrom(
1178 propertyDescriptor.getPropertyType()) && PropertyUtils.isReadable(bo,
1179 propertyDescriptor.getName())) {
1180 Object nestedBo = dataObjectWrapper.getPropertyValueNullSafe(propertyDescriptor.getName());
1181 if (nestedBo instanceof BusinessObject) {
1182 setObjectPropertyDeep(nestedBo, propertyName, type, propertyValue);
1183 }
1184 }
1185
1186
1187 else if (propertyDescriptor.getPropertyType() != null && (List.class).isAssignableFrom(
1188 propertyDescriptor.getPropertyType()) && dataObjectWrapper.getPropertyValueNullSafe(
1189 propertyDescriptor.getName()) != null) {
1190
1191 List propertyList = (List) dataObjectWrapper.getPropertyValueNullSafe(propertyDescriptor.getName());
1192 for (Object listedBo : propertyList) {
1193 if (listedBo != null && listedBo instanceof BusinessObject) {
1194 setObjectPropertyDeep(listedBo, propertyName, type, propertyValue);
1195 }
1196 }
1197 }
1198 }
1199 }
1200
1201 @Override
1202 public boolean hasPrimaryKeyFieldValues(Object dataObject) {
1203 DataObjectWrapper<Object> dataObjectWrapper = dataObjectService.wrap(dataObject);
1204 return dataObjectWrapper.areAllPrimaryKeyAttributesPopulated();
1205 }
1206
1207 @Override
1208 public Class materializeClassForProxiedObject(Object object) {
1209 if (object == null) {
1210 return null;
1211 }
1212 if (LegacyUtils.isKradDataManaged(object.getClass())) {
1213 Object o = resolveProxy(object);
1214 if (o != null) {
1215 return o.getClass();
1216 }
1217 }
1218 return object.getClass();
1219 }
1220
1221 @Override
1222 public Object getNestedValue(Object bo, String fieldName) {
1223 return KradDataServiceLocator.getDataObjectService().wrap(bo).getPropertyValueNullSafe(fieldName);
1224 }
1225
1226 @Override
1227 public Object createNewObjectFromClass(Class clazz) {
1228 if (clazz == null) {
1229 throw new IllegalArgumentException("Class was passed in as null");
1230 }
1231
1232 Object object = null;
1233
1234 try {
1235 object = clazz.newInstance();
1236 } catch (InstantiationException e) {
1237 throw new RuntimeException(e);
1238 } catch (IllegalAccessException e) {
1239 throw new RuntimeException(e);
1240 }
1241
1242 return object;
1243 }
1244
1245 @Override
1246 public boolean isNull(Object object) {
1247 return object == null;
1248 }
1249
1250 @Override
1251 public void setObjectProperty(Object bo, String propertyName, Class propertyType,
1252 Object propertyValue) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
1253 PropertyUtils.setNestedProperty(bo, propertyName, propertyValue);
1254 }
1255
1256 @Override
1257 public <T extends Document> T findByDocumentHeaderId(Class<T> documentClass, String id) {
1258 T document = KRADServiceLocator.getDataObjectService().find(documentClass, id);
1259
1260 ((DocumentAdHocService) KRADServiceLocatorWeb.getService("documentAdHocService")).addAdHocs(document);
1261 return document;
1262 }
1263
1264 @Override
1265 public <T extends Document> List<T> findByDocumentHeaderIds(Class<T> documentClass, List<String> ids) {
1266 List<T> documents = new ArrayList<T>();
1267
1268 for (String id : ids) {
1269 T document = findByDocumentHeaderId(documentClass, id);
1270
1271 if (document != null) {
1272 documents.add(document);
1273 }
1274 }
1275
1276 return documents;
1277 }
1278
1279 @Required
1280 public void setDataObjectService(DataObjectService dataObjectService) {
1281 this.dataObjectService = dataObjectService;
1282 }
1283
1284 @Required
1285 public void setLookupCriteriaGenerator(LookupCriteriaGenerator lookupCriteriaGenerator) {
1286 this.lookupCriteriaGenerator = lookupCriteriaGenerator;
1287 }
1288
1289 @Required
1290 public void setKualiConfigurationService(ConfigurationService kualiConfigurationService) {
1291 this.kualiConfigurationService = kualiConfigurationService;
1292 }
1293
1294 @Required
1295 public void setKualiModuleService(KualiModuleService kualiModuleService) {
1296 this.kualiModuleService = kualiModuleService;
1297 }
1298
1299 @Required
1300 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
1301 this.dataDictionaryService = dataDictionaryService;
1302 }
1303
1304 public ViewDictionaryService getViewDictionaryService() {
1305 return viewDictionaryService;
1306 }
1307
1308 public void setViewDictionaryService(ViewDictionaryService viewDictionaryService) {
1309 this.viewDictionaryService = viewDictionaryService;
1310 }
1311
1312 }