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