1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.maintenance;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
20 import org.kuali.rice.core.api.CoreApiServiceLocator;
21 import org.kuali.rice.core.api.encryption.EncryptionService;
22 import org.kuali.rice.kim.api.identity.Person;
23 import org.kuali.rice.krad.bo.BusinessObject;
24 import org.kuali.rice.krad.bo.DocumentHeader;
25 import org.kuali.rice.krad.bo.Note;
26 import org.kuali.rice.krad.bo.PersistableBusinessObject;
27 import org.kuali.rice.krad.exception.PessimisticLockingException;
28 import org.kuali.rice.krad.service.BusinessObjectService;
29 import org.kuali.rice.krad.service.DataObjectAuthorizationService;
30 import org.kuali.rice.krad.service.DataObjectMetaDataService;
31 import org.kuali.rice.krad.service.DocumentDictionaryService;
32 import org.kuali.rice.krad.service.KRADServiceLocator;
33 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
34 import org.kuali.rice.krad.service.LookupService;
35 import org.kuali.rice.krad.service.MaintenanceDocumentService;
36 import org.kuali.rice.krad.uif.container.CollectionGroup;
37 import org.kuali.rice.krad.uif.service.impl.ViewHelperServiceImpl;
38 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
39 import org.kuali.rice.krad.uif.view.View;
40 import org.kuali.rice.krad.util.KRADConstants;
41 import org.kuali.rice.krad.util.ObjectUtils;
42 import org.kuali.rice.krad.web.form.MaintenanceForm;
43
44 import java.security.GeneralSecurityException;
45 import java.util.ArrayList;
46 import java.util.Collection;
47 import java.util.Iterator;
48 import java.util.List;
49 import java.util.Map;
50
51
52
53
54
55
56 public class MaintainableImpl extends ViewHelperServiceImpl implements Maintainable {
57 private static final long serialVersionUID = 9125271369161634992L;
58
59 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(MaintainableImpl.class);
60
61 private String documentNumber;
62 private Object dataObject;
63 private Class<?> dataObjectClass;
64 private String maintenanceAction;
65
66 private transient LookupService lookupService;
67 private transient DataObjectAuthorizationService dataObjectAuthorizationService;
68 private transient DataObjectMetaDataService dataObjectMetaDataService;
69 private transient DocumentDictionaryService documentDictionaryService;
70 private transient EncryptionService encryptionService;
71 private transient BusinessObjectService businessObjectService;
72 private transient MaintenanceDocumentService maintenanceDocumentService;
73
74
75
76
77 @Override
78 public Object retrieveObjectForEditOrCopy(MaintenanceDocument document, Map<String, String> dataObjectKeys) {
79 Object dataObject = null;
80
81 try {
82 dataObject = getLookupService().findObjectBySearch(getDataObjectClass(), dataObjectKeys);
83 } catch (ClassNotPersistenceCapableException ex) {
84 if (!document.getOldMaintainableObject().isExternalBusinessObject()) {
85 throw new RuntimeException("Data Object Class: "
86 + getDataObjectClass()
87 + " is not persistable and is not externalizable - configuration error");
88 }
89
90 }
91
92 return dataObject;
93 }
94
95
96
97
98 @Override
99 public void setDocumentNumber(String documentNumber) {
100 this.documentNumber = documentNumber;
101 }
102
103
104
105
106 @Override
107 public String getDocumentTitle(MaintenanceDocument document) {
108
109
110 return "";
111 }
112
113
114
115
116 @Override
117 public Object getDataObject() {
118 return dataObject;
119 }
120
121
122
123
124 @Override
125 public void setDataObject(Object object) {
126 this.dataObject = object;
127 }
128
129
130
131
132 @Override
133 public Class getDataObjectClass() {
134 return dataObjectClass;
135 }
136
137
138
139
140 @Override
141 public void setDataObjectClass(Class dataObjectClass) {
142 this.dataObjectClass = dataObjectClass;
143 }
144
145
146
147
148 @Override
149 public String getMaintenanceAction() {
150 return maintenanceAction;
151 }
152
153
154
155
156 @Override
157 public void setMaintenanceAction(String maintenanceAction) {
158 this.maintenanceAction = maintenanceAction;
159 }
160
161
162
163
164
165
166
167 @Override
168 public List<MaintenanceLock> generateMaintenanceLocks() {
169 List<MaintenanceLock> maintenanceLocks = new ArrayList<MaintenanceLock>();
170 StringBuffer lockRepresentation = new StringBuffer(dataObjectClass.getName());
171 lockRepresentation.append(KRADConstants.Maintenance.LOCK_AFTER_CLASS_DELIM);
172
173 Object bo = getDataObject();
174 List keyFieldNames = getDocumentDictionaryService().getLockingKeys(getDocumentTypeName());
175
176 for (Iterator i = keyFieldNames.iterator(); i.hasNext(); ) {
177 String fieldName = (String) i.next();
178 Object fieldValue = ObjectUtils.getPropertyValue(bo, fieldName);
179 if (fieldValue == null) {
180 fieldValue = "";
181 }
182
183
184 if (getDataObjectAuthorizationService()
185 .attributeValueNeedsToBeEncryptedOnFormsAndLinks(dataObjectClass, fieldName)) {
186 try {
187 fieldValue = getEncryptionService().encrypt(fieldValue);
188 } catch (GeneralSecurityException e) {
189 LOG.error("Unable to encrypt secure field for locking representation " + e.getMessage());
190 throw new RuntimeException(
191 "Unable to encrypt secure field for locking representation " + e.getMessage());
192 }
193 }
194
195 lockRepresentation.append(fieldName);
196 lockRepresentation.append(KRADConstants.Maintenance.LOCK_AFTER_FIELDNAME_DELIM);
197 lockRepresentation.append(String.valueOf(fieldValue));
198 if (i.hasNext()) {
199 lockRepresentation.append(KRADConstants.Maintenance.LOCK_AFTER_VALUE_DELIM);
200 }
201 }
202
203 MaintenanceLock maintenanceLock = new MaintenanceLock();
204 maintenanceLock.setDocumentNumber(documentNumber);
205 maintenanceLock.setLockingRepresentation(lockRepresentation.toString());
206 maintenanceLocks.add(maintenanceLock);
207
208 return maintenanceLocks;
209 }
210
211
212
213
214
215 protected String getDocumentTypeName() {
216 return getDocumentDictionaryService().getMaintenanceDocumentTypeName(dataObjectClass);
217 }
218
219
220
221
222 @Override
223 public void saveDataObject() {
224 if (dataObject instanceof PersistableBusinessObject) {
225 if(getMaintenanceAction().equals(KRADConstants.MAINTENANCE_COPY_ACTION)){
226 if(org.apache.commons.lang.StringUtils.isNotBlank(((PersistableBusinessObject) dataObject).getObjectId())){
227 ((PersistableBusinessObject) dataObject).setObjectId("");
228 }
229 if(null!= ((PersistableBusinessObject) dataObject).getVersionNumber()){
230 ((PersistableBusinessObject) dataObject).setVersionNumber(null);
231 }
232 }
233 getBusinessObjectService().linkAndSave((PersistableBusinessObject) dataObject);
234 } else {
235 throw new RuntimeException(
236 "Cannot save object of type: " + dataObjectClass + " with business object service");
237 }
238 }
239
240
241
242
243 @Override
244 public void deleteDataObject() {
245 if (dataObject == null) {
246 return;
247 }
248
249 if (dataObject instanceof PersistableBusinessObject) {
250 getBusinessObjectService().delete((PersistableBusinessObject) dataObject);
251 dataObject = null;
252 } else {
253 throw new RuntimeException(
254 "Cannot delete object of type: " + dataObjectClass + " with business object service");
255 }
256 }
257
258
259
260
261 @Override
262 public void doRouteStatusChange(DocumentHeader documentHeader) {
263
264 }
265
266
267
268
269 @Override
270 public String getLockingDocumentId() {
271 return getMaintenanceDocumentService().getLockingDocumentId(this, documentNumber);
272 }
273
274
275
276
277 @Override
278 public List<String> getWorkflowEngineDocumentIdsToLock() {
279 return null;
280 }
281
282
283
284
285
286
287
288
289
290 @Override
291 public boolean useCustomLockDescriptors() {
292 return false;
293 }
294
295
296
297
298
299
300
301
302 @Override
303 public String getCustomLockDescriptor(Person user) {
304 throw new PessimisticLockingException("The Maintainable for document " + documentNumber +
305 " is using pessimistic locking with custom lock descriptors, but the Maintainable has not overridden the getCustomLockDescriptor method");
306 }
307
308
309
310
311 @Override
312 public boolean isNotesEnabled() {
313 return getDataObjectMetaDataService().areNotesSupported(dataObjectClass);
314 }
315
316
317
318
319 @Override
320 public boolean isExternalBusinessObject() {
321 return false;
322 }
323
324
325
326
327 @Override
328 public void prepareExternalBusinessObject(BusinessObject businessObject) {
329
330 }
331
332
333
334
335
336
337 @Override
338 public boolean isOldDataObjectInDocument() {
339 boolean isOldDataObjectInExistence = true;
340
341 if (getDataObject() == null) {
342 isOldDataObjectInExistence = false;
343 } else {
344 Map<String, ?> keyFieldValues = getDataObjectMetaDataService().getPrimaryKeyFieldValues(getDataObject());
345 for (Object keyValue : keyFieldValues.values()) {
346 if (keyValue == null) {
347 isOldDataObjectInExistence = false;
348 } else if ((keyValue instanceof String) && StringUtils.isBlank((String) keyValue)) {
349 isOldDataObjectInExistence = false;
350 }
351
352 if (!isOldDataObjectInExistence) {
353 break;
354 }
355 }
356 }
357
358 return isOldDataObjectInExistence;
359 }
360
361
362
363
364 @Override
365 public void prepareForSave() {
366
367 }
368
369
370
371
372 @Override
373 public void processAfterRetrieve() {
374
375 }
376
377
378
379
380 @Override
381 public void setupNewFromExisting(MaintenanceDocument document, Map<String, String[]> parameters) {
382
383 }
384
385
386
387
388 @Override
389 public void processAfterCopy(MaintenanceDocument document, Map<String, String[]> requestParameters) {
390
391 }
392
393
394
395
396 @Override
397 public void processAfterEdit(MaintenanceDocument document, Map<String, String[]> requestParameters) {
398
399 }
400
401
402
403
404 @Override
405 public void processAfterNew(MaintenanceDocument document, Map<String, String[]> requestParameters) {
406
407 }
408
409
410
411
412 @Override
413 public void processAfterPost(MaintenanceDocument document, Map<String, String[]> requestParameters) {
414
415 }
416
417
418
419
420
421
422
423
424
425
426
427 @Override
428 protected void processAfterAddLine(View view, CollectionGroup collectionGroup, Object model, Object addLine) {
429 super.processAfterAddLine(view, collectionGroup, model, addLine);
430
431
432 if (model instanceof MaintenanceForm && KRADConstants.MAINTENANCE_EDIT_ACTION.equals(((MaintenanceForm)model).getMaintenanceAction()) && !(addLine instanceof Note)) {
433 MaintenanceForm maintenanceForm = (MaintenanceForm) model;
434 MaintenanceDocument document = maintenanceForm.getDocument();
435
436
437 Collection<Object> oldCollection = ObjectPropertyUtils
438 .getPropertyValue(document.getOldMaintainableObject().getDataObject(),
439 collectionGroup.getPropertyName());
440 try {
441 Object blankLine = collectionGroup.getCollectionObjectClass().newInstance();
442 oldCollection.add(blankLine);
443 } catch (Exception e) {
444 throw new RuntimeException("Unable to create new line instance for old maintenance object", e);
445 }
446 }
447 }
448
449
450
451
452
453
454
455
456 @Override
457 protected void processAfterDeleteLine(View view, CollectionGroup collectionGroup, Object model, int lineIndex) {
458 super.processAfterDeleteLine(view, collectionGroup, model, lineIndex);
459
460
461 if (model instanceof MaintenanceForm && KRADConstants.MAINTENANCE_EDIT_ACTION.equals(((MaintenanceForm)model).getMaintenanceAction())
462 && !collectionGroup.getCollectionObjectClass().getName().equals(Note.class.getName())) {
463 MaintenanceForm maintenanceForm = (MaintenanceForm) model;
464 MaintenanceDocument document = maintenanceForm.getDocument();
465
466
467 Collection<Object> oldCollection = ObjectPropertyUtils
468 .getPropertyValue(document.getOldMaintainableObject().getDataObject(),
469 collectionGroup.getPropertyName());
470 try {
471
472 oldCollection.remove(oldCollection.toArray()[lineIndex]);
473 } catch (Exception e) {
474 throw new RuntimeException("Unable to delete line instance for old maintenance object", e);
475 }
476 }
477 }
478
479
480
481
482
483
484 protected String getDocumentNumber() {
485 return this.documentNumber;
486 }
487
488 protected LookupService getLookupService() {
489 if (lookupService == null) {
490 lookupService = KRADServiceLocatorWeb.getLookupService();
491 }
492 return this.lookupService;
493 }
494
495 public void setLookupService(LookupService lookupService) {
496 this.lookupService = lookupService;
497 }
498
499 protected DataObjectAuthorizationService getDataObjectAuthorizationService() {
500 if (dataObjectAuthorizationService == null) {
501 this.dataObjectAuthorizationService = KRADServiceLocatorWeb.getDataObjectAuthorizationService();
502 }
503 return dataObjectAuthorizationService;
504 }
505
506 public void setDataObjectAuthorizationService(DataObjectAuthorizationService dataObjectAuthorizationService) {
507 this.dataObjectAuthorizationService = dataObjectAuthorizationService;
508 }
509
510 protected DataObjectMetaDataService getDataObjectMetaDataService() {
511 if (dataObjectMetaDataService == null) {
512 this.dataObjectMetaDataService = KRADServiceLocatorWeb.getDataObjectMetaDataService();
513 }
514 return dataObjectMetaDataService;
515 }
516
517 public void setDataObjectMetaDataService(DataObjectMetaDataService dataObjectMetaDataService) {
518 this.dataObjectMetaDataService = dataObjectMetaDataService;
519 }
520
521 public DocumentDictionaryService getDocumentDictionaryService() {
522 if (documentDictionaryService == null) {
523 this.documentDictionaryService = KRADServiceLocatorWeb.getDocumentDictionaryService();
524 }
525 return documentDictionaryService;
526 }
527
528 public void setDocumentDictionaryService(DocumentDictionaryService documentDictionaryService) {
529 this.documentDictionaryService = documentDictionaryService;
530 }
531
532 protected EncryptionService getEncryptionService() {
533 if (encryptionService == null) {
534 encryptionService = CoreApiServiceLocator.getEncryptionService();
535 }
536 return encryptionService;
537 }
538
539 public void setEncryptionService(EncryptionService encryptionService) {
540 this.encryptionService = encryptionService;
541 }
542
543 protected BusinessObjectService getBusinessObjectService() {
544 if (businessObjectService == null) {
545 businessObjectService = KRADServiceLocator.getBusinessObjectService();
546 }
547 return businessObjectService;
548 }
549
550 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
551 this.businessObjectService = businessObjectService;
552 }
553
554 protected MaintenanceDocumentService getMaintenanceDocumentService() {
555 if (maintenanceDocumentService == null) {
556 maintenanceDocumentService = KRADServiceLocatorWeb.getMaintenanceDocumentService();
557 }
558 return maintenanceDocumentService;
559 }
560
561 public void setMaintenanceDocumentService(MaintenanceDocumentService maintenanceDocumentService) {
562 this.maintenanceDocumentService = maintenanceDocumentService;
563 }
564 }