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.util.Collection;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 import org.apache.commons.beanutils.PropertyUtils;
28 import org.apache.commons.lang.StringUtils;
29 import org.kuali.rice.core.api.config.property.ConfigContext;
30 import org.kuali.rice.kim.api.identity.Person;
31 import org.kuali.rice.kim.api.identity.PersonService;
32 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
33 import org.kuali.rice.krad.bo.BusinessObject;
34 import org.kuali.rice.krad.bo.DataObjectRelationship;
35 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
36 import org.kuali.rice.krad.bo.PersistableBusinessObject;
37 import org.kuali.rice.krad.bo.PersistableBusinessObjectBaseAdapter;
38 import org.kuali.rice.krad.dao.BusinessObjectDao;
39 import org.kuali.rice.krad.exception.ObjectNotABusinessObjectRuntimeException;
40 import org.kuali.rice.krad.exception.ReferenceAttributeDoesntExistException;
41 import org.kuali.rice.krad.service.BusinessObjectService;
42 import org.kuali.rice.krad.service.DataObjectMetaDataService;
43 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
44 import org.kuali.rice.krad.service.ModuleService;
45 import org.kuali.rice.krad.service.PersistenceService;
46 import org.kuali.rice.krad.service.PersistenceStructureService;
47 import org.kuali.rice.krad.util.KRADConstants;
48 import org.kuali.rice.krad.util.LegacyDataFramework;
49 import org.kuali.rice.krad.util.ObjectUtils;
50 import org.springframework.transaction.annotation.Transactional;
51
52
53
54
55
56
57
58 @Deprecated
59 @LegacyDataFramework
60 public class BusinessObjectServiceImpl implements BusinessObjectService {
61
62 private PersistenceService persistenceService;
63 private PersistenceStructureService persistenceStructureService;
64 private BusinessObjectDao businessObjectDao;
65 private PersonService personService;
66 private DataObjectMetaDataService dataObjectMetaDataService;
67 private LegacyDataFramework legacyDataFramework;
68
69 private boolean illegalBusinessObjectsForSaveInitialized;
70 private final Set<String> illegalBusinessObjectsForSave = new HashSet<String>();
71
72 @Override
73 @Transactional
74 public <T extends PersistableBusinessObject> T save(T bo) {
75 validateBusinessObjectForSave(bo);
76 return (T) businessObjectDao.save(bo);
77 }
78
79 @Override
80 @Transactional
81 public List<? extends PersistableBusinessObject> save(List<? extends PersistableBusinessObject> businessObjects) {
82 validateBusinessObjectForSave(businessObjects);
83 return businessObjectDao.save(businessObjects);
84 }
85
86 @Override
87 @Transactional
88 public PersistableBusinessObject linkAndSave(PersistableBusinessObject bo) {
89 validateBusinessObjectForSave(bo);
90 persistenceService.linkObjects(bo);
91 return businessObjectDao.save(bo);
92 }
93
94 @Override
95 @Transactional
96 public List<? extends PersistableBusinessObject> linkAndSave(List<? extends PersistableBusinessObject> businessObjects) {
97 validateBusinessObjectForSave(businessObjects);
98 return businessObjectDao.save(businessObjects);
99 }
100
101 protected void validateBusinessObjectForSave(PersistableBusinessObject bo) {
102 if (bo == null) {
103 throw new IllegalArgumentException("Object passed in is null");
104 }
105 if (!isBusinessObjectAllowedForSave(bo)) {
106 throw new IllegalArgumentException("Object passed in is a BusinessObject but has been restricted from save operations according to configuration parameter '" + KRADConstants.Config.ILLEGAL_BUSINESS_OBJECTS_FOR_SAVE);
107 }
108 }
109
110 protected void validateBusinessObjectForSave(List<? extends PersistableBusinessObject> businessObjects) {
111 for (PersistableBusinessObject bo : businessObjects) {
112 if (bo == null) {
113 throw new IllegalArgumentException("One of the objects in the List is null.");
114 }
115 if (!isBusinessObjectAllowedForSave(bo)) {
116 throw new IllegalArgumentException("One of the objects in the List is a BusinessObject but has been restricted from save operations according to configuration parameter '" + KRADConstants.Config.ILLEGAL_BUSINESS_OBJECTS_FOR_SAVE
117 + " Passed in type was '" + bo.getClass().getName() + "'.");
118 }
119 }
120 }
121
122
123
124
125
126
127
128 protected boolean isBusinessObjectAllowedForSave(PersistableBusinessObject bo) {
129 if (!illegalBusinessObjectsForSaveInitialized) {
130 synchronized (this) {
131 boolean applyCheck = true;
132 String applyCheckValue = ConfigContext.getCurrentContextConfig().getProperty(KRADConstants.Config.APPLY_ILLEGAL_BUSINESS_OBJECT_FOR_SAVE_CHECK);
133 if (!StringUtils.isEmpty(applyCheckValue)) {
134 applyCheck = Boolean.valueOf(applyCheckValue);
135 }
136 if (applyCheck) {
137 String illegalBos = ConfigContext.getCurrentContextConfig().getProperty(KRADConstants.Config.ILLEGAL_BUSINESS_OBJECTS_FOR_SAVE);
138 if (!StringUtils.isEmpty(illegalBos)) {
139 String[] illegalBosSplit = illegalBos.split(",");
140 for (String illegalBo : illegalBosSplit) {
141 illegalBusinessObjectsForSave.add(illegalBo.trim());
142 }
143 }
144 }
145 }
146 illegalBusinessObjectsForSaveInitialized = true;
147 }
148 return !illegalBusinessObjectsForSave.contains(bo.getClass().getName());
149 }
150
151
152 @Override
153 public <T extends BusinessObject> T findBySinglePrimaryKey(Class<T> clazz, Object primaryKey) {
154 return businessObjectDao.findBySinglePrimaryKey(clazz, primaryKey);
155 }
156 @Override
157 public <T extends BusinessObject> T findByPrimaryKey(Class<T> clazz, Map<String, ?> primaryKeys) {
158 return businessObjectDao.findByPrimaryKey(clazz, primaryKeys);
159 }
160
161 @Override
162 public Object retrieve(Object object) {
163 return businessObjectDao.retrieve(object);
164 }
165
166 @Override
167 public <T extends BusinessObject> Collection<T> findAll(Class<T> clazz) {
168 return businessObjectDao.findAll(clazz);
169 }
170 @Override
171 public <T extends BusinessObject> Collection<T> findAllOrderBy( Class<T> clazz, String sortField, boolean sortAscending ) {
172 final Map<String, ?> emptyParameters = Collections.emptyMap();
173 return businessObjectDao.findMatchingOrderBy(clazz, emptyParameters, sortField, sortAscending );
174 }
175
176 @Override
177 public <T extends BusinessObject> Collection<T> findMatching(Class<T> clazz, Map<String, ?> fieldValues) {
178 return businessObjectDao.findMatching(clazz, fieldValues);
179 }
180
181 @Override
182 public int countMatching(Class clazz, Map<String, ?> fieldValues) {
183 return businessObjectDao.countMatching(clazz, fieldValues);
184 }
185
186 @Override
187 public int countMatching(Class clazz, Map<String, ?> positiveFieldValues, Map<String, ?> negativeFieldValues) {
188 return businessObjectDao.countMatching(clazz, positiveFieldValues, negativeFieldValues);
189 }
190 @Override
191 public <T extends BusinessObject> Collection<T> findMatchingOrderBy(Class<T> clazz, Map<String, ?> fieldValues, String sortField, boolean sortAscending) {
192 return businessObjectDao.findMatchingOrderBy(clazz, fieldValues, sortField, sortAscending);
193 }
194 @Override
195 @Transactional
196 public void delete(Object bo) {
197
198 if ( bo instanceof List ) {
199 delete( (List<PersistableBusinessObject>)bo );
200 } else {
201 businessObjectDao.delete(bo);
202 }
203 }
204
205 @Override
206 @Transactional
207 public void delete(List<? extends PersistableBusinessObject> boList) {
208 businessObjectDao.delete(boList);
209 }
210
211 @Override
212 @Transactional
213 public void deleteMatching(Class clazz, Map<String, ?> fieldValues) {
214 businessObjectDao.deleteMatching(clazz, fieldValues);
215 }
216
217 @Override
218 public BusinessObject getReferenceIfExists(BusinessObject bo, String referenceName) {
219
220 if (ObjectUtils.isNull(bo)) {
221 throw new IllegalArgumentException("Passed in BusinessObject was null. No processing can be done.");
222 }
223 if (StringUtils.isEmpty(referenceName)) {
224 throw new IllegalArgumentException("Passed in referenceName was empty or null. No processing can be done.");
225 }
226
227
228 PropertyDescriptor propertyDescriptor;
229 try {
230 propertyDescriptor = PropertyUtils.getPropertyDescriptor(bo, referenceName);
231 }
232 catch (Exception e) {
233 throw new RuntimeException(e);
234 }
235 if (propertyDescriptor == null) {
236 throw new ReferenceAttributeDoesntExistException("Requested attribute: '" + referenceName + "' does not exist " + "on class: '" + bo.getClass().getName() + "'. GFK");
237 }
238
239
240 Class referenceClass = null;
241 if(bo instanceof PersistableBusinessObject) {
242 referenceClass = persistenceStructureService.getBusinessObjectAttributeClass(((PersistableBusinessObject)bo).getClass(), referenceName);
243 }
244 if(referenceClass == null) {
245 referenceClass = ObjectUtils.getPropertyType( bo, referenceName, persistenceStructureService );
246 }
247 if ( referenceClass == null ) {
248 referenceClass = propertyDescriptor.getPropertyType();
249 }
250
251
252
253
254 if (ExternalizableBusinessObject.class.isAssignableFrom(referenceClass)) {
255 try {
256 BusinessObject referenceBoExternalizable = (BusinessObject) PropertyUtils.getProperty(bo, referenceName);
257 if (referenceBoExternalizable!=null) {
258 return referenceBoExternalizable;
259 }
260 } catch (Exception ex) {
261
262
263 }
264 }
265
266
267
268 if (!ExternalizableBusinessObject.class.isAssignableFrom(referenceClass) && !PersistableBusinessObject.class.isAssignableFrom(referenceClass)) {
269 throw new ObjectNotABusinessObjectRuntimeException("Attribute requested (" + referenceName + ") is of class: " + "'" + referenceClass.getName() + "' and is not a " + "descendent of PersistableBusinessObject. Only descendents of PersistableBusinessObject " + "can be used.");
270 }
271
272
273
274
275
276 DataObjectRelationship boRel = getDataObjectMetaDataService().getDataObjectRelationship(bo, bo.getClass(),
277 referenceName, "", true, false, false);
278 final Map<String,String> fkMap = boRel != null ? boRel.getParentToChildReferences() : Collections.<String, String>emptyMap();
279
280 boolean allFkeysHaveValues = true;
281
282 Map<String,Object> pkMap = new HashMap<String,Object>();
283 for (Map.Entry<String, String> entry : fkMap.entrySet()) {
284 String fkFieldName = entry.getKey();
285 String pkFieldName = entry.getValue();
286
287
288 Object fkFieldValue;
289 try {
290 fkFieldValue = PropertyUtils.getProperty(bo, fkFieldName);
291 }
292 catch (Exception e) {
293 throw new RuntimeException(e);
294 }
295
296
297 if (ObjectUtils.isNull(fkFieldValue)) {
298 allFkeysHaveValues = false;
299 break;
300 }
301 else if (String.class.isAssignableFrom(fkFieldValue.getClass())) {
302 if (StringUtils.isEmpty((String) fkFieldValue)) {
303 allFkeysHaveValues = false;
304 break;
305 }
306 else {
307 pkMap.put(pkFieldName, fkFieldValue);
308 }
309 }
310
311
312 else {
313 pkMap.put(pkFieldName, fkFieldValue);
314 }
315 }
316
317 BusinessObject referenceBo = null;
318
319 if (allFkeysHaveValues) {
320 if (ExternalizableBusinessObject.class.isAssignableFrom(referenceClass)) {
321 ModuleService responsibleModuleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(referenceClass);
322 if(responsibleModuleService!=null) {
323 return responsibleModuleService.<ExternalizableBusinessObject>getExternalizableBusinessObject(referenceClass, pkMap);
324 }
325 } else
326 referenceBo = this.<BusinessObject>findByPrimaryKey(referenceClass, pkMap);
327 }
328
329
330 return referenceBo;
331 }
332 @Override
333 public void linkUserFields(Object bo) {
334 if (bo == null) {
335 throw new IllegalArgumentException("bo passed in was null");
336 }
337 if ( bo instanceof List ) {
338 linkUserFieldsInBoList( (List<PersistableBusinessObject>) bo );
339 } else {
340 if ( bo instanceof PersistableBusinessObject ) {
341 ((PersistableBusinessObject) bo).linkEditableUserFields();
342 linkUserFieldsInBoList( Collections.<PersistableBusinessObject>singletonList( (PersistableBusinessObject)bo ) );
343 } else if ( bo instanceof PersistableBusinessObjectBaseAdapter ) {
344 ((PersistableBusinessObjectBaseAdapter) bo).linkEditableUserFields();
345 }
346 }
347 }
348
349 protected void linkUserFieldsInBoList(List<PersistableBusinessObject> list) {
350
351
352 if (list == null) {
353 throw new IllegalArgumentException("List of bos passed in was null");
354 } else if (list.isEmpty()) {
355 return;
356 }
357
358 Person person;
359 for (Object obj : list) {
360
361 if ( !(obj instanceof PersistableBusinessObject) ) {
362 continue;
363 }
364 PersistableBusinessObject bo = (PersistableBusinessObject) obj;
365
366 List<DataObjectRelationship> relationships = dataObjectMetaDataService.getDataObjectRelationships(
367 bo.getClass());
368 for ( DataObjectRelationship rel : relationships ) {
369 if ( Person.class.isAssignableFrom( rel.getRelatedClass() ) ) {
370 person = (Person) ObjectUtils.getPropertyValue(bo, rel.getParentAttributeName() );
371 if (person != null) {
372
373 for ( Map.Entry<String,String> entry : rel.getParentToChildReferences().entrySet() ) {
374 if ( "principalId".equals(entry.getValue())) {
375 linkUserReference(bo, person, rel.getParentAttributeName(), entry.getKey() );
376 break;
377 }
378 }
379 }
380 }
381 }
382 if ( persistenceStructureService.isPersistable(bo.getClass())) {
383 Map<String, Class> references = persistenceStructureService.listReferenceObjectFields(bo);
384
385
386 for ( Map.Entry<String, Class> entry : references.entrySet() ) {
387 if (Person.class.isAssignableFrom(entry.getValue())) {
388 person = (Person) ObjectUtils.getPropertyValue(bo, entry.getKey());
389 if (person != null) {
390 String fkFieldName = persistenceStructureService.getForeignKeyFieldName(bo.getClass(), entry.getKey(), "principalId");
391 linkUserReference(bo, person, entry.getKey(), fkFieldName);
392 }
393 }
394 }
395 }
396 }
397 }
398
399
400
401
402
403
404
405
406 private void linkUserReference(PersistableBusinessObject bo, Person user, String refFieldName, String fkFieldName) {
407
408
409 if (StringUtils.isBlank(user.getPrincipalName())) {
410 return;
411 }
412
413
414 Person userFromService = getPersonService().getPersonByPrincipalName(user.getPrincipalName());
415 if (userFromService == null) {
416 return;
417 }
418
419
420 setBoField(bo, fkFieldName, userFromService.getPrincipalId());
421 }
422
423 private void setBoField(PersistableBusinessObject bo, String fieldName, Object fieldValue) {
424 try {
425 ObjectUtils.setObjectProperty(bo, fieldName, fieldValue.getClass(), fieldValue);
426 }
427 catch (Exception e) {
428 throw new RuntimeException("Could not set field [" + fieldName + "] on BO to value: " + fieldValue.toString() + " (see nested exception for details).", e);
429 }
430 }
431
432 @Override
433 public PersistableBusinessObject manageReadOnly(PersistableBusinessObject bo) {
434 return getBusinessObjectDao().manageReadOnly(bo);
435 }
436
437
438
439
440
441
442 protected BusinessObjectDao getBusinessObjectDao() {
443 return businessObjectDao;
444 }
445
446
447
448
449
450
451 public void setBusinessObjectDao(BusinessObjectDao businessObjectDao) {
452 this.businessObjectDao = businessObjectDao;
453 }
454
455
456
457
458
459
460 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
461 this.persistenceStructureService = persistenceStructureService;
462 }
463
464
465
466
467 public final void setPersonService(PersonService personService) {
468 this.personService = personService;
469 }
470
471 protected PersonService getPersonService() {
472 return personService != null ? personService : (personService = KimApiServiceLocator.getPersonService());
473 }
474
475
476
477
478
479
480 public final void setPersistenceService(PersistenceService persistenceService) {
481 this.persistenceService = persistenceService;
482 }
483
484 protected DataObjectMetaDataService getDataObjectMetaDataService() {
485 return dataObjectMetaDataService;
486 }
487
488 public void setDataObjectMetaDataService(DataObjectMetaDataService dataObjectMetadataService) {
489 this.dataObjectMetaDataService = dataObjectMetadataService;
490 }
491
492 }