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