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