/** @see org.kuali.rice.krad.service.DocumentService */
  @Override
  public void sendNoteRouteNotification(Document document, Note note, Person sender)
      throws WorkflowException {
    AdHocRouteRecipient routeRecipient = note.getAdHocRouteRecipient();

    // build notification request
    Person requestedUser = this.getPersonService().getPersonByPrincipalName(routeRecipient.getId());
    String senderName = sender.getFirstName() + " " + sender.getLastName();
    String requestedName = requestedUser.getFirstName() + " " + requestedUser.getLastName();

    String notificationText =
        kualiConfigurationService.getPropertyValueAsString(
            RiceKeyConstants.MESSAGE_NOTE_NOTIFICATION_ANNOTATION);
    if (StringUtils.isBlank(notificationText)) {
      throw new RuntimeException(
          "No annotation message found for note notification. Message needs added to application resources with key:"
              + RiceKeyConstants.MESSAGE_NOTE_NOTIFICATION_ANNOTATION);
    }
    notificationText =
        MessageFormat.format(
            notificationText, new Object[] {senderName, requestedName, note.getNoteText()});

    List<AdHocRouteRecipient> routeRecipients = new ArrayList<AdHocRouteRecipient>();
    routeRecipients.add(routeRecipient);

    workflowDocumentService.sendWorkflowNotification(
        document.getDocumentHeader().getWorkflowDocument(),
        notificationText,
        routeRecipients,
        KRADConstants.NOTE_WORKFLOW_NOTIFICATION_REQUEST_LABEL);

    // clear recipient allowing an notification to be sent to another person
    note.setAdHocRouteRecipient(new AdHocRoutePerson());
  }
  /**
   * @see
   *     org.kuali.rice.krad.service.DocumentService#getByDocumentHeaderIdSessionless(java.lang.String)
   */
  @Override
  public Document getByDocumentHeaderIdSessionless(String documentHeaderId)
      throws WorkflowException {
    if (documentHeaderId == null) {
      throw new IllegalArgumentException("invalid (null) documentHeaderId");
    }

    WorkflowDocument workflowDocument = null;

    if (LOG.isDebugEnabled()) {
      LOG.debug("Retrieving doc id: " + documentHeaderId + " from workflow service.");
    }

    Person person = getPersonService().getPersonByPrincipalName(KRADConstants.SYSTEM_USER);
    workflowDocument = workflowDocumentService.loadWorkflowDocument(documentHeaderId, person);

    Class<? extends Document> documentClass =
        getDocumentClassByTypeName(workflowDocument.getDocumentTypeName());

    // retrieve the Document
    Document document =
        getLegacyDataAdapter().findByDocumentHeaderId(documentClass, documentHeaderId);

    return postProcessDocument(documentHeaderId, workflowDocument, document);
  }
  /**
   * Creates a new ProtocolReviewDocument.
   *
   * <p>Handles creating the workflow document, and the underlying ProtocolReview BO linking the
   * protocol, submission, and reviewer.
   *
   * @param protocolSubmission The protocol submission
   * @param protocolReviewerBean The bean that holds
   * @param documentDescription the description for the created document
   * @param documentExplanation the explanation for the created document
   * @param documentOrganizationNumber the organizationNumber for the created document
   * @param principalId The principalId to use when creating the workflow document. Usually this
   *     should be the principal of the user creating the review.
   * @return
   * @throws WorkflowException
   */
  protected ProtocolOnlineReviewDocumentBase createProtocolOnlineReviewDocument(
      ProtocolSubmissionBase protocolSubmission,
      ProtocolReviewer protocolReviewer,
      String documentDescription,
      String documentExplanation,
      String documentOrganizationDocumentNumber,
      Date dateRequested,
      Date dateDue,
      String principalId)
      throws WorkflowException {

    ProtocolOnlineReviewDocumentBase protocolReviewDocument;

    Person person = personService.getPerson(principalId);
    WorkflowDocument workflowDocument =
        workflowDocumentService.createWorkflowDocument(getProtocolOLRDocumentTypeHook(), person);

    DocumentHeader docHeader = new DocumentHeader();
    docHeader.setWorkflowDocument(workflowDocument);
    docHeader.setDocumentNumber(workflowDocument.getDocumentId().toString());
    protocolReviewDocument = getNewProtocolOnlineReviewDocumentInstanceHook();
    protocolReviewDocument.setDocumentNumber(docHeader.getDocumentNumber());
    protocolReviewDocument.setDocumentHeader(docHeader);

    protocolReviewDocument.getProtocolOnlineReview().setProtocol(protocolSubmission.getProtocol());

    protocolReviewDocument
        .getProtocolOnlineReview()
        .setProtocolId(protocolSubmission.getProtocolId());

    protocolReviewDocument.getProtocolOnlineReview().setProtocolSubmission(protocolSubmission);
    protocolReviewDocument
        .getProtocolOnlineReview()
        .setSubmissionIdFk(protocolSubmission.getSubmissionId());
    protocolReviewDocument
        .getProtocolOnlineReview()
        .setProtocolOnlineReviewStatusCode(getProtocolOLRSavedStatusCodeHook());
    protocolReviewDocument
        .getProtocolOnlineReview()
        .setDateRequested(
            dateRequested == null ? new Date((new java.util.Date()).getTime()) : dateRequested);
    protocolReviewDocument.getProtocolOnlineReview().setDateDue(dateDue);

    protocolReviewDocument
        .getProtocolOnlineReview()
        .setProtocolReviewerId(protocolReviewer.getProtocolReviewerId());
    protocolReviewDocument.getProtocolOnlineReview().setProtocolReviewer(protocolReviewer);

    docHeader.setDocumentDescription(documentDescription);
    docHeader.setOrganizationDocumentNumber(documentOrganizationDocumentNumber);
    docHeader.setExplanation(documentExplanation);

    documentService.saveDocument(protocolReviewDocument);
    return protocolReviewDocument;
  }