001package org.kuali.rice.krad.service.impl; 002 003/** 004 * Created by maheswarang on 12/17/14. 005 */ 006 007import org.apache.commons.lang.StringUtils; 008import org.apache.commons.lang.time.StopWatch; 009import org.kuali.ole.alert.bo.AlertBo; 010import org.kuali.ole.alert.bo.AlertEvent; 011import org.kuali.ole.alert.bo.AlertEventField; 012import org.kuali.ole.alert.document.OlePersistableBusinessObjectBase; 013import org.kuali.ole.alert.document.OleTransactionalDocumentBase; 014import org.kuali.ole.alert.service.AlertGlobalConfigurationServiceImpl; 015import org.kuali.ole.alert.service.impl.AlertServiceImpl; 016import org.kuali.ole.deliver.bo.OleDeliverRequestType; 017import org.kuali.rice.core.api.CoreApiServiceLocator; 018import org.kuali.rice.core.api.config.ConfigurationException; 019import org.kuali.rice.core.api.config.property.ConfigurationService; 020import org.kuali.rice.core.api.datetime.DateTimeService; 021import org.kuali.rice.core.api.util.RiceKeyConstants; 022import org.kuali.rice.core.framework.persistence.jta.TransactionalNoValidationExceptionRollback; 023import org.kuali.rice.kew.api.WorkflowDocument; 024import org.kuali.rice.kew.api.exception.WorkflowException; 025import org.kuali.rice.kim.api.identity.Person; 026import org.kuali.rice.kim.api.identity.PersonService; 027import org.kuali.rice.kim.api.services.KimApiServiceLocator; 028import org.kuali.rice.krad.UserSession; 029import org.kuali.rice.krad.UserSessionUtils; 030import org.kuali.rice.krad.bo.*; 031import org.kuali.rice.krad.dao.DocumentDao; 032import org.kuali.rice.krad.datadictionary.exception.UnknownDocumentTypeException; 033import org.kuali.rice.krad.document.Document; 034import org.kuali.rice.krad.document.DocumentAuthorizer; 035import org.kuali.rice.krad.document.DocumentPresentationController; 036import org.kuali.rice.krad.exception.DocumentAuthorizationException; 037import org.kuali.rice.krad.exception.ValidationException; 038import org.kuali.rice.krad.maintenance.MaintenanceDocument; 039import org.kuali.rice.krad.maintenance.MaintenanceDocumentBase; 040import org.kuali.rice.krad.rules.rule.event.*; 041import org.kuali.rice.krad.service.*; 042import org.kuali.rice.krad.util.GlobalVariables; 043import org.kuali.rice.krad.util.KRADConstants; 044import org.kuali.rice.krad.util.NoteType; 045import org.kuali.rice.krad.util.ObjectUtils; 046import org.kuali.rice.krad.workflow.service.WorkflowDocumentService; 047import org.springframework.dao.OptimisticLockingFailureException; 048 049import java.lang.reflect.Constructor; 050import java.lang.reflect.InvocationTargetException; 051import java.text.MessageFormat; 052import java.util.ArrayList; 053import java.util.HashMap; 054import java.util.List; 055import java.util.Map; 056 057 058/** 059 * Service implementation for the Document structure. It contains all of the document level type of 060 * processing and calling back into documents for various centralization of functionality. This is the default, 061 * Kuali delivered implementation which utilizes Workflow. 062 * 063 * @author Kuali Rice Team (rice.collab@kuali.org) 064 */ 065@TransactionalNoValidationExceptionRollback 066public class DocumentServiceImpl implements DocumentService { 067 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentServiceImpl.class); 068 069 private DocumentDao documentDao; 070 071 private DateTimeService dateTimeService; 072 private NoteService noteService; 073 private WorkflowDocumentService workflowDocumentService; 074 private BusinessObjectService businessObjectService; 075 private DataDictionaryService dataDictionaryService; 076 private DocumentHeaderService documentHeaderService; 077 private DocumentDictionaryService documentDictionaryService; 078 private PersonService personService; 079 private ConfigurationService kualiConfigurationService; 080 081 public AlertServiceImpl getAlertService(){ 082 return new AlertServiceImpl(); 083 } 084 085 /** 086 * @see org.kuali.rice.krad.service.DocumentService#saveDocument(org.kuali.rice.krad.document.Document) 087 */ 088 @Override 089 public Document saveDocument(Document document) throws WorkflowException, ValidationException { 090 return saveDocument(document, SaveDocumentEvent.class); 091 } 092 093 @Override 094 public Document saveDocument(Document document, 095 Class<? extends KualiDocumentEvent> kualiDocumentEventClass) throws WorkflowException, ValidationException { 096 checkForNulls(document); 097 if (kualiDocumentEventClass == null) { 098 throw new IllegalArgumentException("invalid (null) kualiDocumentEventClass"); 099 } 100 // if event is not an instance of a SaveDocumentEvent or a SaveOnlyDocumentEvent 101 if (!SaveEvent.class.isAssignableFrom(kualiDocumentEventClass)) { 102 throw new ConfigurationException("The KualiDocumentEvent class '" + kualiDocumentEventClass.getName() + 103 "' does not implement the class '" + SaveEvent.class.getName() + "'"); 104 } 105// if (!getDocumentActionFlags(document).getCanSave()) { 106// throw buildAuthorizationException("save", document); 107// } 108 document.prepareForSave(); 109 Document savedDocument = validateAndPersistDocumentAndSaveAdHocRoutingRecipients(document, 110 generateKualiDocumentEvent(document, kualiDocumentEventClass)); 111 prepareWorkflowDocument(savedDocument); 112 getWorkflowDocumentService().save(savedDocument.getDocumentHeader().getWorkflowDocument(), null); 113 114 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 115 savedDocument.getDocumentHeader().getWorkflowDocument()); 116 if(document instanceof OleTransactionalDocumentBase){ 117 OleTransactionalDocumentBase oleTransactionalDocumentBase = (OleTransactionalDocumentBase)document; 118 getAlertService().deleteAlerts(document.getDocumentNumber()); 119 getAlertService().saveAlert(oleTransactionalDocumentBase); 120 List<AlertBo> alertBos = oleTransactionalDocumentBase.getAlertBoList(); 121 oleTransactionalDocumentBase = (OleTransactionalDocumentBase)savedDocument; 122 oleTransactionalDocumentBase.setAlertBoList(alertBos); 123 124 } 125 126 if(document instanceof MaintenanceDocumentBase){ 127 MaintenanceDocumentBase maintenanceDocumentBase = (MaintenanceDocumentBase) document; 128 if(maintenanceDocumentBase.getDocumentDataObject() instanceof OlePersistableBusinessObjectBase){ 129 OlePersistableBusinessObjectBase olePersistableBusinessObjectBase = (OlePersistableBusinessObjectBase)maintenanceDocumentBase.getDocumentDataObject(); 130 getAlertService().deleteAlerts(maintenanceDocumentBase.getDocumentNumber()); 131 getAlertService().deleteAlerts(document.getDocumentNumber()); 132 getAlertService().saveAlert(maintenanceDocumentBase); 133 134 } 135 } 136 137 return savedDocument; 138 } 139 140 private KualiDocumentEvent generateKualiDocumentEvent(Document document, 141 Class<? extends KualiDocumentEvent> eventClass) throws ConfigurationException { 142 String potentialErrorMessage = 143 "Found error trying to generate Kuali Document Event using event class '" + eventClass.getName() + 144 "' for document " + document.getDocumentNumber(); 145 146 try { 147 Constructor<?> usableConstructor = null; 148 List<Object> paramList = new ArrayList<Object>(); 149 for (Constructor<?> currentConstructor : eventClass.getConstructors()) { 150 for (Class<?> parameterClass : currentConstructor.getParameterTypes()) { 151 if (Document.class.isAssignableFrom(parameterClass)) { 152 usableConstructor = currentConstructor; 153 paramList.add(document); 154 } else { 155 paramList.add(null); 156 } 157 } 158 if (ObjectUtils.isNotNull(usableConstructor)) { 159 break; 160 } 161 } 162 if (usableConstructor == null) { 163 throw new RuntimeException("Cannot find a constructor for class '" + eventClass.getName() + 164 "' that takes in a document parameter"); 165 } 166 return (KualiDocumentEvent) usableConstructor.newInstance(paramList.toArray()); 167 } catch (SecurityException e) { 168 throw new ConfigurationException(potentialErrorMessage, e); 169 } catch (IllegalArgumentException e) { 170 throw new ConfigurationException(potentialErrorMessage, e); 171 } catch (InstantiationException e) { 172 throw new ConfigurationException(potentialErrorMessage, e); 173 } catch (IllegalAccessException e) { 174 throw new ConfigurationException(potentialErrorMessage, e); 175 } catch (InvocationTargetException e) { 176 throw new ConfigurationException(potentialErrorMessage, e); 177 } 178 } 179 180 /** 181 * @see org.kuali.rice.krad.service.DocumentService#routeDocument(org.kuali.rice.krad.document.Document, 182 * String, java.util.List) 183 */ 184 @Override 185 public Document routeDocument(Document document, String annotation, 186 List<AdHocRouteRecipient> adHocRecipients) throws ValidationException, WorkflowException { 187 checkForNulls(document); 188 //if (!getDocumentActionFlags(document).getCanRoute()) { 189 // throw buildAuthorizationException("route", document); 190 //} 191 document.prepareForSave(); 192 Document savedDocument = validateAndPersistDocument(document, new RouteDocumentEvent(document)); 193 prepareWorkflowDocument(savedDocument); 194 getWorkflowDocumentService() 195 .route(savedDocument.getDocumentHeader().getWorkflowDocument(), annotation, adHocRecipients); 196 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 197 savedDocument.getDocumentHeader().getWorkflowDocument()); 198 removeAdHocPersonsAndWorkgroups(savedDocument); 199 if(document instanceof OleTransactionalDocumentBase){ 200 OleTransactionalDocumentBase oleTransactionalDocumentBase = (OleTransactionalDocumentBase)document; 201 getAlertService().deleteAlerts(document.getDocumentNumber()); 202 getAlertService().saveAlert(oleTransactionalDocumentBase); 203 List<AlertBo> alertBos = oleTransactionalDocumentBase.getAlertBoList(); 204 oleTransactionalDocumentBase = (OleTransactionalDocumentBase)savedDocument; 205 oleTransactionalDocumentBase.setAlertBoList(alertBos); 206 processGlobalAlerts(document); 207 } 208 if(document instanceof MaintenanceDocumentBase){ 209 MaintenanceDocumentBase maintenanceDocumentBase = (MaintenanceDocumentBase) document; 210 if(maintenanceDocumentBase.getDocumentDataObject() instanceof OlePersistableBusinessObjectBase){ 211 OlePersistableBusinessObjectBase olePersistableBusinessObjectBase = (OlePersistableBusinessObjectBase)maintenanceDocumentBase.getDocumentDataObject(); 212 getAlertService().deleteAlerts(maintenanceDocumentBase.getDocumentNumber()); 213 getAlertService().deleteAlerts(document.getDocumentNumber()); 214 getAlertService().saveAlert(maintenanceDocumentBase); 215 processGlobalAlerts(document); 216 } 217 } 218 return savedDocument; 219 } 220 221 /** 222 * @see org.kuali.rice.krad.service.DocumentService#approveDocument(org.kuali.rice.krad.document.Document, 223 * String, 224 * java.util.List) 225 */ 226 @Override 227 public Document approveDocument(Document document, String annotation, 228 List<AdHocRouteRecipient> adHocRecipients) throws ValidationException, WorkflowException { 229 checkForNulls(document); 230 //if (!getDocumentActionFlags(document).getCanApprove()) { 231 // throw buildAuthorizationException("approve", document); 232 //} 233 document.prepareForSave(); 234 Document savedDocument = validateAndPersistDocument(document, new ApproveDocumentEvent(document)); 235 prepareWorkflowDocument(savedDocument); 236 getWorkflowDocumentService() 237 .approve(savedDocument.getDocumentHeader().getWorkflowDocument(), annotation, adHocRecipients); 238 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 239 savedDocument.getDocumentHeader().getWorkflowDocument()); 240 removeAdHocPersonsAndWorkgroups(savedDocument); 241 return savedDocument; 242 } 243 244 /** 245 * @see org.kuali.rice.krad.service.DocumentService#superUserApproveDocument(org.kuali.rice.krad.document.Document, 246 * String) 247 */ 248 @Override 249 public Document superUserApproveDocument(Document document, String annotation) throws WorkflowException { 250 getDocumentDao().save(document); 251 prepareWorkflowDocument(document); 252 getWorkflowDocumentService().superUserApprove(document.getDocumentHeader().getWorkflowDocument(), annotation); 253 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 254 document.getDocumentHeader().getWorkflowDocument()); 255 removeAdHocPersonsAndWorkgroups(document); 256 return document; 257 } 258 259 /** 260 * @see org.kuali.rice.krad.service.DocumentService#superUserCancelDocument(org.kuali.rice.krad.document.Document, 261 * String) 262 */ 263 @Override 264 public Document superUserCancelDocument(Document document, String annotation) throws WorkflowException { 265 getDocumentDao().save(document); 266 prepareWorkflowDocument(document); 267 getWorkflowDocumentService().superUserCancel(document.getDocumentHeader().getWorkflowDocument(), annotation); 268 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 269 document.getDocumentHeader().getWorkflowDocument()); 270 removeAdHocPersonsAndWorkgroups(document); 271 return document; 272 } 273 274 /** 275 * @see org.kuali.rice.krad.service.DocumentService#superUserCancelDocument(org.kuali.rice.krad.document.Document, 276 * String) 277 */ 278 @Override 279 public Document superUserDisapproveDocument(Document document, String annotation) throws WorkflowException { 280 getDocumentDao().save(document); 281 return superUserDisapproveDocumentWithoutSaving(document, annotation); 282 } 283 284 /** 285 * @see org.kuali.rice.krad.service.DocumentService#superUserCancelDocument(org.kuali.rice.krad.document.Document, 286 * String) 287 */ 288 @Override 289 public Document superUserDisapproveDocumentWithoutSaving(Document document, String annotation) throws WorkflowException { 290 prepareWorkflowDocument(document); 291 getWorkflowDocumentService() 292 .superUserDisapprove(document.getDocumentHeader().getWorkflowDocument(), annotation); 293 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 294 document.getDocumentHeader().getWorkflowDocument()); 295 removeAdHocPersonsAndWorkgroups(document); 296 return document; 297 } 298 299 300 /** 301 * @see org.kuali.rice.krad.service.DocumentService#disapproveDocument(org.kuali.rice.krad.document.Document, 302 * String) 303 */ 304 @Override 305 public Document disapproveDocument(Document document, String annotation) throws Exception { 306 checkForNulls(document); 307 308 Note note = createNoteFromDocument(document, annotation); 309 //if note type is BO, override and link disapprove notes to Doc Header 310 if (document.getNoteType().equals(NoteType.BUSINESS_OBJECT)) { 311 note.setNoteTypeCode(NoteType.DOCUMENT_HEADER.getCode()); 312 note.setRemoteObjectIdentifier(document.getDocumentHeader().getObjectId()); 313 } 314 document.addNote(note); 315 316 //SAVE THE NOTE 317 //Note: This save logic is replicated here and in KualiDocumentAction, when to save (based on doc state) should be moved 318 // into a doc service method 319 getNoteService().save(note); 320 321 prepareWorkflowDocument(document); 322 getWorkflowDocumentService().disapprove(document.getDocumentHeader().getWorkflowDocument(), annotation); 323 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 324 document.getDocumentHeader().getWorkflowDocument()); 325 removeAdHocPersonsAndWorkgroups(document); 326 return document; 327 } 328 329 /** 330 * @see org.kuali.rice.krad.service.DocumentService#cancelDocument(org.kuali.rice.krad.document.Document, 331 * String) 332 */ 333 @Override 334 public Document cancelDocument(Document document, String annotation) throws WorkflowException { 335 checkForNulls(document); 336 //if (!getDocumentActionFlags(document).getCanCancel()) { 337 // throw buildAuthorizationException("cancel", document); 338 //} 339 if (document instanceof MaintenanceDocument) { 340 MaintenanceDocument maintDoc = ((MaintenanceDocument) document); 341 if (maintDoc.getOldMaintainableObject() != null && 342 (maintDoc.getOldMaintainableObject().getDataObject() instanceof BusinessObject)) { 343 ((BusinessObject) maintDoc.getOldMaintainableObject().getDataObject()).refresh(); 344 } 345 346 if (maintDoc.getNewMaintainableObject().getDataObject() instanceof BusinessObject) { 347 ((BusinessObject) maintDoc.getNewMaintainableObject().getDataObject()).refresh(); 348 } 349 } 350 prepareWorkflowDocument(document); 351 getWorkflowDocumentService().cancel(document.getDocumentHeader().getWorkflowDocument(), annotation); 352 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 353 document.getDocumentHeader().getWorkflowDocument()); 354 //getBusinessObjectService().delete(document.getAdHocRoutePersons()); 355 //getBusinessObjectService().delete(document.getAdHocRouteWorkgroups()); 356 removeAdHocPersonsAndWorkgroups(document); 357 return document; 358 } 359 360 @Override 361 public Document recallDocument(Document document, String annotation, boolean cancel) throws WorkflowException { 362 checkForNulls(document); 363 364 Note note = createNoteFromDocument(document, annotation); 365 document.addNote(note); 366 getNoteService().save(note); 367 368 prepareWorkflowDocument(document); 369 getWorkflowDocumentService().recall(document.getDocumentHeader().getWorkflowDocument(), annotation, cancel); 370 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 371 document.getDocumentHeader().getWorkflowDocument()); 372 removeAdHocPersonsAndWorkgroups(document); 373 return document; 374 } 375 376 /** 377 * @see org.kuali.rice.krad.service.DocumentService#acknowledgeDocument(org.kuali.rice.krad.document.Document, 378 * String, 379 * java.util.List) 380 */ 381 @Override 382 public Document acknowledgeDocument(Document document, String annotation, 383 List<AdHocRouteRecipient> adHocRecipients) throws WorkflowException { 384 checkForNulls(document); 385 //if (!getDocumentActionFlags(document).getCanAcknowledge()) { 386 // throw buildAuthorizationException("acknowledge", document); 387 //} 388 prepareWorkflowDocument(document); 389 getWorkflowDocumentService() 390 .acknowledge(document.getDocumentHeader().getWorkflowDocument(), annotation, adHocRecipients); 391 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 392 document.getDocumentHeader().getWorkflowDocument()); 393 removeAdHocPersonsAndWorkgroups(document); 394 return document; 395 } 396 397 /** 398 * @see org.kuali.rice.krad.service.DocumentService#blanketApproveDocument(org.kuali.rice.krad.document.Document, 399 * String, 400 * java.util.List) 401 */ 402 @Override 403 public Document blanketApproveDocument(Document document, String annotation, 404 List<AdHocRouteRecipient> adHocRecipients) throws ValidationException, WorkflowException { 405 checkForNulls(document); 406 //if (!getDocumentActionFlags(document).getCanBlanketApprove()) { 407 // throw buildAuthorizationException("blanket approve", document); 408 //} 409 document.prepareForSave(); 410 Document savedDocument = validateAndPersistDocument(document, new BlanketApproveDocumentEvent(document)); 411 prepareWorkflowDocument(savedDocument); 412 getWorkflowDocumentService() 413 .blanketApprove(savedDocument.getDocumentHeader().getWorkflowDocument(), annotation, adHocRecipients); 414 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 415 savedDocument.getDocumentHeader().getWorkflowDocument()); 416 removeAdHocPersonsAndWorkgroups(savedDocument); 417 return savedDocument; 418 } 419 420 /** 421 * @see org.kuali.rice.krad.service.DocumentService#clearDocumentFyi(org.kuali.rice.krad.document.Document, 422 * java.util.List) 423 */ 424 @Override 425 public Document clearDocumentFyi(Document document, 426 List<AdHocRouteRecipient> adHocRecipients) throws WorkflowException { 427 checkForNulls(document); 428 // populate document content so searchable attributes will be indexed properly 429 document.populateDocumentForRouting(); 430 getWorkflowDocumentService().clearFyi(document.getDocumentHeader().getWorkflowDocument(), adHocRecipients); 431 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 432 document.getDocumentHeader().getWorkflowDocument()); 433 removeAdHocPersonsAndWorkgroups(document); 434 return document; 435 } 436 437 /** 438 * @see org.kuali.rice.krad.service.DocumentService#completeDocument(org.kuali.rice.krad.document.Document, 439 * String, 440 * java.util.List) 441 */ 442 @Override 443 public Document completeDocument(Document document, String annotation, 444 List adHocRecipients) throws WorkflowException { 445 checkForNulls(document); 446 447 document.prepareForSave(); 448 validateAndPersistDocument(document, new CompleteDocumentEvent(document)); 449 450 prepareWorkflowDocument(document); 451 getWorkflowDocumentService().complete(document.getDocumentHeader().getWorkflowDocument(), annotation, 452 adHocRecipients); 453 454 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 455 document.getDocumentHeader().getWorkflowDocument()); 456 457 removeAdHocPersonsAndWorkgroups(document); 458 459 return document; 460 } 461 462 protected void checkForNulls(Document document) { 463 if (document == null) { 464 throw new IllegalArgumentException("invalid (null) document"); 465 } 466 if (document.getDocumentNumber() == null) { 467 throw new IllegalStateException("invalid (null) documentHeaderId"); 468 } 469 } 470 471 private Document validateAndPersistDocumentAndSaveAdHocRoutingRecipients(Document document, 472 KualiDocumentEvent event) { 473 /* 474 * Using this method to wrap validateAndPersistDocument to keep everything in one transaction. This avoids modifying the 475 * signature on validateAndPersistDocument method 476 */ 477 List<AdHocRouteRecipient> adHocRoutingRecipients = new ArrayList<AdHocRouteRecipient>(); 478 adHocRoutingRecipients.addAll(document.getAdHocRoutePersons()); 479 adHocRoutingRecipients.addAll(document.getAdHocRouteWorkgroups()); 480 481 for (AdHocRouteRecipient recipient : adHocRoutingRecipients) { 482 recipient.setdocumentNumber(document.getDocumentNumber()); 483 } 484 Map<String, String> criteria = new HashMap<String, String>(); 485 criteria.put("documentNumber", document.getDocumentNumber()); 486 getBusinessObjectService().deleteMatching(AdHocRouteRecipient.class, criteria); 487 488 getBusinessObjectService().save(adHocRoutingRecipients); 489 return validateAndPersistDocument(document, event); 490 } 491 492 /** 493 * @see org.kuali.rice.krad.service.DocumentService#documentExists(String) 494 */ 495 @Override 496 public boolean documentExists(String documentHeaderId) { 497 // validate parameters 498 if (StringUtils.isBlank(documentHeaderId)) { 499 throw new IllegalArgumentException("invalid (blank) documentHeaderId"); 500 } 501 502 boolean internalUserSession = false; 503 try { 504 // KFSMI-2543 - allowed method to run without a user session so it can be used 505 // by workflow processes 506 if (GlobalVariables.getUserSession() == null) { 507 internalUserSession = true; 508 GlobalVariables.setUserSession(new UserSession(KRADConstants.SYSTEM_USER)); 509 GlobalVariables.clear(); 510 } 511 512 // look for workflowDocumentHeader, since that supposedly won't break the transaction 513 if (getWorkflowDocumentService().workflowDocumentExists(documentHeaderId)) { 514 // look for docHeaderId, since that fails without breaking the transaction 515 return getDocumentHeaderService().getDocumentHeaderById(documentHeaderId) != null; 516 } 517 518 return false; 519 } finally { 520 // if a user session was established for this call, clear it our 521 if (internalUserSession) { 522 GlobalVariables.clear(); 523 GlobalVariables.setUserSession(null); 524 } 525 } 526 } 527 528 /** 529 * Creates a new document by class. 530 * 531 * @see org.kuali.rice.krad.service.DocumentService#getNewDocument(Class) 532 */ 533 @Override 534 public Document getNewDocument(Class<? extends Document> documentClass) throws WorkflowException { 535 if (documentClass == null) { 536 throw new IllegalArgumentException("invalid (null) documentClass"); 537 } 538 if (!Document.class.isAssignableFrom(documentClass)) { 539 throw new IllegalArgumentException("invalid (non-Document) documentClass"); 540 } 541 542 String documentTypeName = getDataDictionaryService().getDocumentTypeNameByClass(documentClass); 543 if (StringUtils.isBlank(documentTypeName)) { 544 throw new UnknownDocumentTypeException( 545 "unable to get documentTypeName for unknown documentClass '" + documentClass.getName() + "'"); 546 } 547 return getNewDocument(documentTypeName); 548 } 549 550 /** 551 * Creates a new document by document type name. The principal name 552 * passed in will be used as the document initiator. If the initiatorPrincipalNm 553 * is null or blank, the current user will be used. 554 * 555 * @see org.kuali.rice.krad.service.DocumentService#getNewDocument(String, String) 556 */ 557 @Override 558 public Document getNewDocument(String documentTypeName, String initiatorPrincipalNm) throws WorkflowException { 559 560 // argument validation 561 String watchName = "DocumentServiceImpl.getNewDocument"; 562 StopWatch watch = new StopWatch(); 563 watch.start(); 564 if (LOG.isDebugEnabled()) { 565 LOG.debug(watchName + ": started"); 566 } 567 if (StringUtils.isBlank(documentTypeName)) { 568 throw new IllegalArgumentException("invalid (blank) documentTypeName"); 569 } 570 if (GlobalVariables.getUserSession() == null) { 571 throw new IllegalStateException( 572 "GlobalVariables must be populated with a valid UserSession before a new document can be created"); 573 } 574 575 // get the class for this docTypeName 576 Class<? extends Document> documentClass = getDocumentClassByTypeName(documentTypeName); 577 578 // get the initiator 579 Person initiator = null; 580 if (StringUtils.isBlank(initiatorPrincipalNm)) { 581 initiator = GlobalVariables.getUserSession().getPerson(); 582 } else { 583 initiator = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(initiatorPrincipalNm); 584 if (ObjectUtils.isNull(initiator)) { 585 initiator = GlobalVariables.getUserSession().getPerson(); 586 } 587 } 588 589 // get the authorization 590 DocumentAuthorizer documentAuthorizer = getDocumentDictionaryService().getDocumentAuthorizer(documentTypeName); 591 DocumentPresentationController documentPresentationController = 592 getDocumentDictionaryService().getDocumentPresentationController(documentTypeName); 593 // make sure this person is authorized to initiate 594 LOG.debug("calling canInitiate from getNewDocument()"); 595 if (!documentPresentationController.canInitiate(documentTypeName) || 596 !documentAuthorizer.canInitiate(documentTypeName, initiator)) { 597 throw new DocumentAuthorizationException(initiator.getPrincipalName(), "initiate", documentTypeName); 598 } 599 600 // initiate new workflow entry, get the workflow doc 601 WorkflowDocument workflowDocument = getWorkflowDocumentService().createWorkflowDocument(documentTypeName, initiator); 602 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), workflowDocument); 603 604 // create a new document header object 605 DocumentHeader documentHeader = null; 606 try { 607 // create a new document header object 608 Class<? extends DocumentHeader> documentHeaderClass = 609 getDocumentHeaderService().getDocumentHeaderBaseClass(); 610 documentHeader = documentHeaderClass.newInstance(); 611 documentHeader.setWorkflowDocument(workflowDocument); 612 documentHeader.setDocumentNumber(workflowDocument.getDocumentId()); 613 // status and notes are initialized correctly in the constructor 614 } catch (IllegalAccessException e) { 615 throw new RuntimeException("Error instantiating DocumentHeader", e); 616 } catch (InstantiationException e) { 617 throw new RuntimeException("Error instantiating DocumentHeader", e); 618 } 619 620 // build Document of specified type 621 Document document = null; 622 try { 623 // all maintenance documents have same class 624 if (MaintenanceDocumentBase.class.isAssignableFrom(documentClass)) { 625 Class<?>[] defaultConstructor = new Class[]{String.class}; 626 Constructor<? extends Document> cons = documentClass.getConstructor(defaultConstructor); 627 if (ObjectUtils.isNull(cons)) { 628 throw new ConfigurationException( 629 "Could not find constructor with document type name parameter needed for Maintenance Document Base class"); 630 } 631 document = cons.newInstance(documentTypeName); 632 } else { 633 // non-maintenance document 634 document = documentClass.newInstance(); 635 } 636 } catch (IllegalAccessException e) { 637 throw new RuntimeException("Error instantiating Document", e); 638 } catch (InstantiationException e) { 639 throw new RuntimeException("Error instantiating Document", e); 640 } catch (SecurityException e) { 641 throw new RuntimeException("Error instantiating Maintenance Document", e); 642 } catch (NoSuchMethodException e) { 643 throw new RuntimeException( 644 "Error instantiating Maintenance Document: No constructor with String parameter found", e); 645 } catch (IllegalArgumentException e) { 646 throw new RuntimeException("Error instantiating Maintenance Document", e); 647 } catch (InvocationTargetException e) { 648 throw new RuntimeException("Error instantiating Maintenance Document", e); 649 } 650 651 document.setDocumentHeader(documentHeader); 652 document.setDocumentNumber(documentHeader.getDocumentNumber()); 653 654 watch.stop(); 655 if (LOG.isDebugEnabled()) { 656 LOG.debug(watchName + ": " + watch.toString()); 657 } 658 659 return document; 660 } 661 662 /** 663 * Creates a new document by document type name. 664 * 665 * @see org.kuali.rice.krad.service.DocumentService#getNewDocument(String) 666 */ 667 @Override 668 public Document getNewDocument(String documentTypeName) throws WorkflowException { 669 return getNewDocument(documentTypeName, null); 670 } 671 672 673 /** 674 * This is temporary until workflow 2.0 and reads from a table to get documents whose status has changed to A 675 * (approved - no 676 * outstanding approval actions requested) 677 * 678 * @param documentHeaderId 679 * @return Document 680 * @throws org.kuali.rice.kew.api.exception.WorkflowException 681 */ 682 @Override 683 public Document getByDocumentHeaderId(String documentHeaderId) throws WorkflowException { 684 if (documentHeaderId == null) { 685 throw new IllegalArgumentException("invalid (null) documentHeaderId"); 686 } 687 boolean internalUserSession = false; 688 try { 689 // KFSMI-2543 - allowed method to run without a user session so it can be used 690 // by workflow processes 691 if (GlobalVariables.getUserSession() == null) { 692 internalUserSession = true; 693 GlobalVariables.setUserSession(new UserSession(KRADConstants.SYSTEM_USER)); 694 GlobalVariables.clear(); 695 } 696 697 WorkflowDocument workflowDocument = null; 698 699 if (LOG.isDebugEnabled()) { 700 LOG.debug("Retrieving doc id: " + documentHeaderId + " from workflow service."); 701 } 702 workflowDocument = getWorkflowDocumentService() 703 .loadWorkflowDocument(documentHeaderId, GlobalVariables.getUserSession().getPerson()); 704 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), workflowDocument); 705 706 Class<? extends Document> documentClass = getDocumentClassByTypeName(workflowDocument.getDocumentTypeName()); 707 708 // retrieve the Document 709 Document document = getDocumentDao().findByDocumentHeaderId(documentClass, documentHeaderId); 710 711 return postProcessDocument(documentHeaderId, workflowDocument, document); 712 } finally { 713 // if a user session was established for this call, clear it out 714 if (internalUserSession) { 715 GlobalVariables.clear(); 716 GlobalVariables.setUserSession(null); 717 } 718 } 719 } 720 721 /** 722 * @see org.kuali.rice.krad.service.DocumentService#getByDocumentHeaderIdSessionless(String) 723 */ 724 @Override 725 public Document getByDocumentHeaderIdSessionless(String documentHeaderId) throws WorkflowException { 726 if (documentHeaderId == null) { 727 throw new IllegalArgumentException("invalid (null) documentHeaderId"); 728 } 729 730 WorkflowDocument workflowDocument = null; 731 732 if (LOG.isDebugEnabled()) { 733 LOG.debug("Retrieving doc id: " + documentHeaderId + " from workflow service."); 734 } 735 736 Person person = getPersonService().getPersonByPrincipalName(KRADConstants.SYSTEM_USER); 737 workflowDocument = workflowDocumentService.loadWorkflowDocument(documentHeaderId, person); 738 739 Class<? extends Document> documentClass = getDocumentClassByTypeName(workflowDocument.getDocumentTypeName()); 740 741 // retrieve the Document 742 Document document = getDocumentDao().findByDocumentHeaderId(documentClass, documentHeaderId); 743 744 return postProcessDocument(documentHeaderId, workflowDocument, document); 745 } 746 747 private Class<? extends Document> getDocumentClassByTypeName(String documentTypeName) { 748 if (StringUtils.isBlank(documentTypeName)) { 749 throw new IllegalArgumentException("invalid (blank) documentTypeName"); 750 } 751 752 Class<? extends Document> clazz = getDataDictionaryService().getDocumentClassByTypeName(documentTypeName); 753 if (clazz == null) { 754 throw new UnknownDocumentTypeException( 755 "unable to get class for unknown documentTypeName '" + documentTypeName + "'"); 756 } 757 return clazz; 758 } 759 760 /** 761 * Loads the Notes for the note target on this Document. 762 * 763 * @param document the document for which to load the notes 764 */ 765 protected void loadNotes(Document document) { 766 if (isNoteTargetReady(document)) { 767 List<Note> notes = new ArrayList<Note>(); 768 if (StringUtils.isNotBlank(document.getNoteTarget().getObjectId())) { 769 notes.addAll(getNoteService().getByRemoteObjectId(document.getNoteTarget().getObjectId())); 770 } 771 //notes created on 'disapprove' are linked to Doc Header, so this checks that even if notetype = BO 772 if (document.getNoteType().equals(NoteType.BUSINESS_OBJECT) 773 && document.getDocumentHeader().getWorkflowDocument().isDisapproved()) { 774 notes.addAll(getNoteService().getByRemoteObjectId(document.getDocumentHeader().getObjectId())); 775 } 776 777 // KULRNE-5692 - force a refresh of the attachments 778 // they are not (non-updateable) references and don't seem to update properly upon load 779 for (Note note : notes) { 780 note.refreshReferenceObject("attachment"); 781 } 782 document.setNotes(notes); 783 } 784 } 785 786 /** 787 * Performs required post-processing for every document from the documentDao 788 * 789 * @param documentHeaderId 790 * @param workflowDocument 791 * @param document 792 */ 793 private Document postProcessDocument(String documentHeaderId, WorkflowDocument workflowDocument, Document document) { 794 if (document != null) { 795 document.getDocumentHeader().setWorkflowDocument(workflowDocument); 796 document.processAfterRetrieve(); 797 loadNotes(document); 798 } 799 return document; 800 } 801 802 /** 803 * The default implementation - this retrieves all documents by a list of documentHeader for a given class. 804 * 805 * @see org.kuali.rice.krad.service.DocumentService#getDocumentsByListOfDocumentHeaderIds(Class, 806 * java.util.List) 807 */ 808 @Override 809 public List<Document> getDocumentsByListOfDocumentHeaderIds(Class<? extends Document> documentClass, 810 List<String> documentHeaderIds) throws WorkflowException { 811 // validate documentHeaderIdList and contents 812 if (documentHeaderIds == null) { 813 throw new IllegalArgumentException("invalid (null) documentHeaderId list"); 814 } 815 int index = 0; 816 for (String documentHeaderId : documentHeaderIds) { 817 if (StringUtils.isBlank(documentHeaderId)) { 818 throw new IllegalArgumentException("invalid (blank) documentHeaderId at list index " + index); 819 } 820 index++; 821 } 822 823 boolean internalUserSession = false; 824 try { 825 // KFSMI-2543 - allowed method to run without a user session so it can be used 826 // by workflow processes 827 if (GlobalVariables.getUserSession() == null) { 828 internalUserSession = true; 829 GlobalVariables.setUserSession(new UserSession(KRADConstants.SYSTEM_USER)); 830 GlobalVariables.clear(); 831 } 832 833 // retrieve all documents that match the document header ids 834 List<? extends Document> rawDocuments = 835 getDocumentDao().findByDocumentHeaderIds(documentClass, documentHeaderIds); 836 837 // post-process them 838 List<Document> documents = new ArrayList<Document>(); 839 for (Document document : rawDocuments) { 840 WorkflowDocument workflowDocument = getWorkflowDocumentService().loadWorkflowDocument(document.getDocumentNumber(), GlobalVariables.getUserSession().getPerson()); 841 842 document = postProcessDocument(document.getDocumentNumber(), workflowDocument, document); 843 documents.add(document); 844 } 845 return documents; 846 } finally { 847 // if a user session was established for this call, clear it our 848 if (internalUserSession) { 849 GlobalVariables.clear(); 850 GlobalVariables.setUserSession(null); 851 } 852 } 853 } 854 855 /* Helper Methods */ 856 857 /** 858 * Validates and persists a document. 859 */ 860 @Override 861 public Document validateAndPersistDocument(Document document, KualiDocumentEvent event) throws ValidationException { 862 if (document == null) { 863 LOG.error("document passed to validateAndPersist was null"); 864 throw new IllegalArgumentException("invalid (null) document"); 865 } 866 if (LOG.isDebugEnabled()) { 867 LOG.debug("validating and preparing to persist document " + document.getDocumentNumber()); 868 } 869 870 document.validateBusinessRules(event); 871 document.prepareForSave(event); 872 873 // save the document 874 Document savedDocument = null; 875 try { 876 if (LOG.isInfoEnabled()) { 877 LOG.info("storing document " + document.getDocumentNumber()); 878 } 879 savedDocument = getDocumentDao().save(document); 880 } catch (OptimisticLockingFailureException e) { 881 LOG.error("exception encountered on store of document " + e.getMessage()); 882 throw e; 883 } 884 885 boolean notesSaved = saveDocumentNotes(document); 886 if (!notesSaved) { 887 if (LOG.isInfoEnabled()) { 888 LOG.info( 889 "Notes not saved during validateAndPersistDocument, likely means that note save needs to be deferred because note target is not ready."); 890 } 891 } 892 893 savedDocument.postProcessSave(event); 894 895 return savedDocument; 896 } 897 898 /** 899 * Sets the title and app document id in the flex document 900 * 901 * @param document 902 * @throws org.kuali.rice.kew.api.exception.WorkflowException 903 */ 904 @Override 905 public void prepareWorkflowDocument(Document document) throws WorkflowException { 906 // populate document content so searchable attributes will be indexed properly 907 document.populateDocumentForRouting(); 908 909 // make sure we push the document title into the workflowDocument 910 populateDocumentTitle(document); 911 912 // make sure we push the application document id into the workflowDocument 913 populateApplicationDocumentId(document); 914 } 915 916 /** 917 * This method will grab the generated document title from the document and add it to the workflowDocument so that 918 * it gets pushed into 919 * workflow when routed. 920 * 921 * @param document 922 * @throws org.kuali.rice.kew.api.exception.WorkflowException 923 */ 924 private void populateDocumentTitle(Document document) throws WorkflowException { 925 String documentTitle = document.getDocumentTitle(); 926 if (StringUtils.isNotBlank(documentTitle)) { 927 document.getDocumentHeader().getWorkflowDocument().setTitle(documentTitle); 928 } 929 } 930 931 /** 932 * This method will grab the organization document number from the document and add it to the workflowDocument so 933 * that it gets pushed 934 * into workflow when routed. 935 * 936 * @param document 937 */ 938 private void populateApplicationDocumentId(Document document) { 939 String organizationDocumentNumber = document.getDocumentHeader().getOrganizationDocumentNumber(); 940 if (StringUtils.isNotBlank(organizationDocumentNumber)) { 941 document.getDocumentHeader().getWorkflowDocument().setApplicationDocumentId(organizationDocumentNumber); 942 } 943 } 944 945 /** 946 * This is to allow for updates of document statuses and other related requirements for updates outside of the 947 * initial save and 948 * route 949 */ 950 @Override 951 public Document updateDocument(Document document) { 952 checkForNulls(document); 953 return getDocumentDao().save(document); 954 } 955 956 /** 957 * @see org.kuali.rice.krad.service.DocumentService#createNoteFromDocument(org.kuali.rice.krad.document.Document, 958 * String) 959 */ 960 @Override 961 public Note createNoteFromDocument(Document document, String text) { 962 Note note = new Note(); 963 964 note.setNotePostedTimestamp(getDateTimeService().getCurrentTimestamp()); 965 note.setVersionNumber(Long.valueOf(1)); 966 note.setNoteText(text); 967 note.setNoteTypeCode(document.getNoteType().getCode()); 968 969 PersistableBusinessObject bo = document.getNoteTarget(); 970 // TODO gah! this is awful 971 Person kualiUser = GlobalVariables.getUserSession().getPerson(); 972 if (kualiUser == null) { 973 throw new IllegalStateException("Current UserSession has a null Person."); 974 } 975 return bo == null ? null : getNoteService().createNote(note, bo, kualiUser.getPrincipalId()); 976 } 977 978 /** 979 * @see org.kuali.rice.krad.service.DocumentService#saveDocumentNotes(org.kuali.rice.krad.document.Document) 980 */ 981 @Override 982 public boolean saveDocumentNotes(Document document) { 983 if (isNoteTargetReady(document)) { 984 List<Note> notes = document.getNotes(); 985 for (Note note : document.getNotes()) { 986 linkNoteRemoteObjectId(note, document.getNoteTarget()); 987 } 988 getNoteService().saveNoteList(notes); 989 return true; 990 } 991 return false; 992 } 993 994 /** 995 * @see org.kuali.rice.krad.service.DocumentService 996 */ 997 @Override 998 public void sendNoteRouteNotification(Document document, Note note, Person sender) throws WorkflowException { 999 AdHocRouteRecipient routeRecipient = note.getAdHocRouteRecipient(); 1000 1001 // build notification request 1002 Person requestedUser = this.getPersonService().getPersonByPrincipalName(routeRecipient.getId()); 1003 String senderName = sender.getFirstName() + " " + sender.getLastName(); 1004 String requestedName = requestedUser.getFirstName() + " " + requestedUser.getLastName(); 1005 1006 String notificationText = 1007 kualiConfigurationService.getPropertyValueAsString( 1008 RiceKeyConstants.MESSAGE_NOTE_NOTIFICATION_ANNOTATION); 1009 if (StringUtils.isBlank(notificationText)) { 1010 throw new RuntimeException( 1011 "No annotation message found for note notification. Message needs added to application resources with key:" + 1012 RiceKeyConstants.MESSAGE_NOTE_NOTIFICATION_ANNOTATION); 1013 } 1014 notificationText = 1015 MessageFormat.format(notificationText, new Object[]{senderName, requestedName, note.getNoteText()}); 1016 1017 List<AdHocRouteRecipient> routeRecipients = new ArrayList<AdHocRouteRecipient>(); 1018 routeRecipients.add(routeRecipient); 1019 1020 workflowDocumentService 1021 .sendWorkflowNotification(document.getDocumentHeader().getWorkflowDocument(), notificationText, 1022 routeRecipients, KRADConstants.NOTE_WORKFLOW_NOTIFICATION_REQUEST_LABEL); 1023 1024 // clear recipient allowing an notification to be sent to another person 1025 note.setAdHocRouteRecipient(new AdHocRoutePerson()); 1026 } 1027 1028 /** 1029 * Determines if the given document's note target is ready for notes to be 1030 * attached and persisted against it. This method verifies that the document's 1031 * note target is non-null as well as checking that it has a non-empty object id. 1032 * 1033 * @param document the document on which to check for note target readiness 1034 * @return true if the note target is ready, false otherwise 1035 */ 1036 protected boolean isNoteTargetReady(Document document) { 1037 1038 //special case for disappoved documents 1039 if (document.getDocumentHeader().getWorkflowDocument().isDisapproved()) { 1040 return true; 1041 } 1042 PersistableBusinessObject noteTarget = document.getNoteTarget(); 1043 if (noteTarget == null || StringUtils.isBlank(noteTarget.getObjectId())) { 1044 return false; 1045 } 1046 return true; 1047 } 1048 1049 private void linkNoteRemoteObjectId(Note note, PersistableBusinessObject noteTarget) { 1050 String objectId = noteTarget.getObjectId(); 1051 if (StringUtils.isBlank(objectId)) { 1052 throw new IllegalStateException( 1053 "Attempted to link a Note with a PersistableBusinessObject with no object id"); 1054 } 1055 note.setRemoteObjectIdentifier(noteTarget.getObjectId()); 1056 } 1057 1058 /** 1059 * @see org.kuali.rice.krad.service.DocumentService#sendAdHocRequests(org.kuali.rice.krad.document.Document, String, java.util.List) 1060 */ 1061 @Override 1062 public void sendAdHocRequests(Document document, String annotation, 1063 List<AdHocRouteRecipient> adHocRecipients) throws WorkflowException { 1064 prepareWorkflowDocument(document); 1065 getWorkflowDocumentService() 1066 .sendWorkflowNotification(document.getDocumentHeader().getWorkflowDocument(), annotation, 1067 adHocRecipients); 1068 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), 1069 document.getDocumentHeader().getWorkflowDocument()); 1070 //getBusinessObjectService().delete(document.getAdHocRoutePersons()); 1071 //getBusinessObjectService().delete(document.getAdHocRouteWorkgroups()); 1072 removeAdHocPersonsAndWorkgroups(document); 1073 } 1074 1075 private void removeAdHocPersonsAndWorkgroups(Document document) { 1076 List<AdHocRoutePerson> adHocRoutePersons = new ArrayList<AdHocRoutePerson>(); 1077 List<AdHocRouteWorkgroup> adHocRouteWorkgroups = new ArrayList<AdHocRouteWorkgroup>(); 1078 getBusinessObjectService().delete(document.getAdHocRoutePersons()); 1079 getBusinessObjectService().delete(document.getAdHocRouteWorkgroups()); 1080 document.setAdHocRoutePersons(adHocRoutePersons); 1081 document.setAdHocRouteWorkgroups(adHocRouteWorkgroups); 1082 } 1083 1084 public void setDateTimeService(DateTimeService dateTimeService) { 1085 this.dateTimeService = dateTimeService; 1086 } 1087 1088 protected DateTimeService getDateTimeService() { 1089 if (this.dateTimeService == null) { 1090 this.dateTimeService = CoreApiServiceLocator.getDateTimeService(); 1091 } 1092 return this.dateTimeService; 1093 } 1094 1095 public void setNoteService(NoteService noteService) { 1096 this.noteService = noteService; 1097 } 1098 1099 protected NoteService getNoteService() { 1100 if (this.noteService == null) { 1101 this.noteService = KRADServiceLocator.getNoteService(); 1102 } 1103 return this.noteService; 1104 } 1105 1106 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 1107 this.businessObjectService = businessObjectService; 1108 } 1109 1110 protected BusinessObjectService getBusinessObjectService() { 1111 if (this.businessObjectService == null) { 1112 this.businessObjectService = KRADServiceLocator.getBusinessObjectService(); 1113 } 1114 return this.businessObjectService; 1115 } 1116 1117 public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) { 1118 this.workflowDocumentService = workflowDocumentService; 1119 } 1120 1121 protected WorkflowDocumentService getWorkflowDocumentService() { 1122 if (this.workflowDocumentService == null) { 1123 this.workflowDocumentService = KRADServiceLocatorWeb.getWorkflowDocumentService(); 1124 } 1125 return this.workflowDocumentService; 1126 } 1127 1128 public void setDocumentDao(DocumentDao documentDao) { 1129 this.documentDao = documentDao; 1130 } 1131 1132 protected DocumentDao getDocumentDao() { 1133 return documentDao; 1134 } 1135 1136 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) { 1137 this.dataDictionaryService = dataDictionaryService; 1138 } 1139 1140 protected DataDictionaryService getDataDictionaryService() { 1141 if (this.dataDictionaryService == null) { 1142 this.dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService(); 1143 } 1144 return this.dataDictionaryService; 1145 } 1146 1147 public void setDocumentHeaderService(DocumentHeaderService documentHeaderService) { 1148 this.documentHeaderService = documentHeaderService; 1149 } 1150 1151 protected DocumentHeaderService getDocumentHeaderService() { 1152 if (this.documentHeaderService == null) { 1153 this.documentHeaderService = KRADServiceLocatorWeb.getDocumentHeaderService(); 1154 } 1155 return this.documentHeaderService; 1156 } 1157 1158 protected DocumentDictionaryService getDocumentDictionaryService() { 1159 if (documentDictionaryService == null) { 1160 documentDictionaryService = KRADServiceLocatorWeb.getDocumentDictionaryService(); 1161 } 1162 return documentDictionaryService; 1163 } 1164 1165 public void setDocumentDictionaryService(DocumentDictionaryService documentDictionaryService) { 1166 this.documentDictionaryService = documentDictionaryService; 1167 } 1168 1169 public PersonService getPersonService() { 1170 if (personService == null) { 1171 personService = KimApiServiceLocator.getPersonService(); 1172 } 1173 return personService; 1174 } 1175 1176 public void setKualiConfigurationService(ConfigurationService kualiConfigurationService) { 1177 this.kualiConfigurationService = kualiConfigurationService; 1178 } 1179 1180 1181 public void processGlobalAlerts(Document document){ 1182 1183 AlertGlobalConfigurationServiceImpl alertGlobalConfigurationService = new AlertGlobalConfigurationServiceImpl(); 1184 alertGlobalConfigurationService.processAlert(document); 1185 //get the class name 1186 //get the alert document 1187 //get the events 1188 //pass the event and object 1189 //get the value form the object using reflection 1190 //check for the conditions if everything get passed for the enent then send mail or alert based on the role user and group id and send the alert 1191 1192 /* AlertEvent alertEvent = new AlertEvent(); 1193 alertEvent.setActive(true); 1194 alertEvent.setAlertDocumentClassName("org.kuali.ole.deliver.bo.OleDeliverRequestType"); 1195 alertEvent.setAlertDocumentTypeName("DLVR_TYP_t"); 1196 AlertEventField alertEventField = new AlertEventField(); 1197 alertEventField.setActive(true); 1198 alertEventField.setAlertFieldName("active"); 1199 alertEventField.setAlertFieldType("boolean"); 1200 alertEventField.setAlertFieldValue("true"); 1201 alertEventField.setAlertCriteria("equalTo"); 1202 // alertEventField.setAlertCriteria("notEqualTo"); 1203 AlertEventField alertEventField1 = new AlertEventField(); 1204 alertEventField1.setActive(true); 1205 alertEventField1.setAlertFieldValue("Mahesh"); 1206 alertEventField1.setAlertFieldType("String"); 1207 alertEventField1.setAlertFieldName("requestTypeCode"); 1208 // alertEventField1.setAlertCriteria("equalTo"); 1209 alertEventField1.setAlertCriteria("notEqualTo"); 1210 1211 AlertEventField alertEventField2= new AlertEventField(); 1212 alertEventField2.setAlertFieldName("requestInteger"); 1213 // alertEventField2.setAlertCriteria("equalTo"); 1214 alertEventField2.setAlertCriteria("greaterThanOrEqualTo"); 1215 *//* alertEventField2.setAlertCriteria("equalTo"); 1216 alertEventField2.setAlertCriteria("equalTo"); 1217 alertEventField2.setAlertCriteria("equalTo"); 1218 alertEventField2.setAlertCriteria("equalTo"); 1219 alertEventField2.setAlertCriteria("equalTo");*//* 1220 alertEventField2.setAlertFieldType("Integer"); 1221 alertEventField2.setAlertFieldValue("10"); 1222 List<AlertEventField> alertEventFieldList = new ArrayList<AlertEventField>(); 1223 // alertEventFieldList.add(alertEventField); 1224 //alertEventFieldList.add(alertEventField1); 1225 alertEventFieldList.add(alertEventField2); 1226 alertEvent.setAlertEventFieldList(alertEventFieldList); 1227 OleDeliverRequestType oleDeliverRequestType = new OleDeliverRequestType(); 1228 oleDeliverRequestType.setActive(true); 1229 oleDeliverRequestType.setRequestTypeCode("kumar"); 1230 oleDeliverRequestType.setRequestInteger(100); 1231 AlertGlobalConfigurationServiceImpl alertGlobalConfigurationService = new AlertGlobalConfigurationServiceImpl(); 1232 alertGlobalConfigurationService.processEvent(alertEvent,oleDeliverRequestType);*/ 1233 } 1234 1235}