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