/**
  * Returns a map containing the token name (<code>String</code>) as key and token value (<code>
  * String</code>) as value. This map can be used to substitute the token name with the token value
  * in a string.
  *
  * <p>Override this method to define additional substitution values for the token processor.
  *
  * @param request request context for the exit, assumed not <code>null</code>, used to obtain the
  *     values for the tokens
  * @return the map containing the token name and values. This map contains non-<code>null</code>
  *     value for all supported token names. The value may be empty if this token does not the
  *     corresponding property defined in "rxconfig/Workflow/rxworkflow.properties" file and a
  *     non-empty value could not be obtained from the request context object. If a non-<code>null
  *     </code> and non-empty value is obtained from the request context then it is used as the
  *     token value, otherwise the value configured in "rxconfig/Workflow/rxworkflow.properties"
  *     file is used (which defaults to empty if no property containing the token name as key is
  *     defined).
  */
 @Deprecated
 protected Map<String, String> getTokenValues(IPSRequestContext request) {
   Map<String, String> tokenValues = new HashMap<String, String>(MAIL_TOKENS_DEFAULT_VALUE);
   for (int i = 0; i < MAIL_TOKENS.length; i++) {
     String tokenName = MAIL_TOKENS[i];
     if (tokenName.equals(WORKFLOW_COMMENT_TOKEN)) {
       String transitionComment =
           PSWorkFlowUtils.getTransitionCommentFromHTMLParams(request.getParameters());
       if ((transitionComment != null) && (transitionComment.trim().length() > 0)) {
         tokenValues.put(tokenName, transitionComment);
       }
     }
   }
   return tokenValues;
 }
  /**
   * Process the notification messages.
   *
   * @see
   *     com.percussion.extension.IPSResultDocumentProcessor#processResultDocument(java.lang.Object[],
   *     com.percussion.server.IPSRequestContext, org.w3c.dom.Document)
   */
  public Document processResultDocument(Object[] params, IPSRequestContext request, Document resDoc)
      throws PSParameterMismatchException, PSExtensionProcessingException {
    log.debug("Entering Notification");
    PSWorkFlowUtils.printWorkflowMessage(
        request, "\nNotify Assignees: enter processResultDocument ");
    int transitionID = 0;
    int toStateID = 0;
    int fromStateID = 0;
    int contentID = 0;
    int workflowID = 0;
    int revisionID = 0;
    String userName = null;
    PSWorkFlowContext wfContext = null;
    PSTransitionsContext tc = null;
    PSWorkflowRoleInfo wfRoleInfo = null;
    PSContentStatusContext csc = null;
    String contentURL = null;
    String lang = null;
    PSConnectionMgr connectionMgr = null;
    Connection connection = null;
    try {
      if (null == request) {
        throw new PSExtensionProcessingException(
            m_fullExtensionName, new IllegalArgumentException("The request must not be null"));
      }
      lang = (String) request.getSessionPrivateObject(PSI18nUtils.USER_SESSION_OBJECT_SYS_LANG);
      if (lang == null) lang = PSI18nUtils.DEFAULT_LANG;
      wfContext =
          (PSWorkFlowContext)
              request.getPrivateObject(IPSWorkFlowContext.WORKFLOW_CONTEXT_PRIVATE_OBJECT);
      if (null == wfContext) {
        log.debug("No transition, no notification sent");
        PSWorkFlowUtils.printWorkflowMessage(
            request,
            "Notify assignees: - no transition was performed - " + "no notifications will be sent");
        return resDoc;
      }
      revisionID = wfContext.getBaseRevisionNum();
      transitionID = wfContext.getTransitionID();
      if (IPSConstants.TRANSITIONID_NO_ACTION_TAKEN == transitionID
          || IPSConstants.TRANSITIONID_CHECKINOUT == transitionID) {
        PSWorkFlowUtils.printWorkflowMessage(
            request,
            "Notify assignees: - no transition was performed - " + "no notifications will be sent");
        return resDoc; // no action at all - no history
      }
      workflowID = wfContext.getWorkflowID();
      toStateID = wfContext.getStateID();
      // Note: we could get content id from workflow context
      if (null == params[0] || 0 == params[0].toString().trim().length()) {
        log.debug("no content id, no notification sent");
        return resDoc; // no content id means no notifications!
      }
      contentID = new Integer(params[0].toString()).intValue();
      if (0 == contentID) {
        log.debug("content id = 0, no notification sent");
        return resDoc; // no content id means no notifications!
      }
      if (null == params[1] || 0 == params[1].toString().trim().length()) {
        throw new PSInvalidParameterTypeException(lang, IPSExtensionErrors.EMPTY_USRNAME1);
      }
      userName = params[1].toString();
      // Get the connection
      connectionMgr = new PSConnectionMgr();
      connection = connectionMgr.getConnection();
      /*
       * get the old state id from the transition context TODO - put the old
       * state id into the workflow context, to avoid database reads.
       */
      tc = new PSTransitionsContext(transitionID, workflowID, connection);
      tc.close();
      fromStateID = tc.getTransitionFromStateID();
      wfRoleInfo =
          (PSWorkflowRoleInfo)
              request.getPrivateObject(PSWorkflowRoleInfo.WORKFLOW_ROLE_INFO_PRIVATE_OBJECT);
      if (null == wfRoleInfo) {
        throw new PSExtensionProcessingException(
            m_fullExtensionName, new PSRoleException(lang, IPSExtensionErrors.ROLEINFO_OBJ_NULL));
      }
      contentURL = PSWorkFlowUtils.getContentItemURL(contentID, revisionID, request, true);
      csc = new PSContentStatusContext(connection, contentID);
      sendNotifications(
          contentURL,
          contentID,
          workflowID,
          transitionID,
          fromStateID,
          toStateID,
          userName,
          wfRoleInfo,
          request,
          connection,
          String.valueOf(csc.getCommunityID()));

    } catch (PSNotificationSkipException se) {
      log.debug("Notification Skipped");
    } catch (PSExtensionProcessingException pe) {
      log.error(
          "Error while sending notification with user " + userName + " and contentid " + contentID,
          pe);
      throw (PSExtensionProcessingException) pe.fillInStackTrace();
    } catch (Exception e) {
      log.error(
          "Error while sending notification with user " + userName + " and contentid " + contentID,
          e);
      // error message should be improved
      String language = null;
      // if(e instanceof PSEntryNotFoundException || e instanceof
      // PSInvalidParameterTypeException )
      // {
      // language = e.getLanguageString();
      // }
      if (language == null) language = PSI18nUtils.DEFAULT_LANG;
      throw new PSExtensionProcessingException(language, m_fullExtensionName, e);
    } finally {
      if (csc != null) {
        try {
          csc.close();
        } catch (Exception ex) {
          // no-op
        }
      }
      try {
        if (null != connectionMgr) connectionMgr.releaseConnection();
      } catch (SQLException sqe) {
      }
      log.debug("End of notification");
      PSWorkFlowUtils.printWorkflowMessage(
          request, "Notify Assignees: exit processResultDocument ");
    }
    return resDoc;
  }