/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2011 Aimluck,Inc.
 * http://www.aipo.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.aimluck.eip.webmail;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.mail.Address;
import javax.mail.Message;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;

import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.jetspeed.capability.CapabilityMap;
import org.apache.jetspeed.capability.CapabilityMapFactory;
import org.apache.jetspeed.om.registry.MediaTypeEntry;
import org.apache.jetspeed.services.Registry;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.resources.JetspeedResources;
import org.apache.jetspeed.util.template.JetspeedLink;
import org.apache.jetspeed.util.template.JetspeedLinkFactory;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.commons.field.ALNumberField;
import com.aimluck.commons.field.ALStringField;
import com.aimluck.commons.utils.ALStringUtil;
import com.aimluck.eip.cayenne.om.portlet.AvzTMailSend;
import com.aimluck.eip.cayenne.om.portlet.EipMAddressbook;
import com.aimluck.eip.cayenne.om.portlet.EipMMailAccount;
import com.aimluck.eip.cayenne.om.portlet.EipTMail;
import com.aimluck.eip.cayenne.om.portlet.EipTMailFolder;
import com.aimluck.eip.cayenne.om.security.TurbineUser;
import com.aimluck.eip.common.ALAbstractFormWindow;
import com.aimluck.eip.common.ALBaseUser;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALEipGroupSend;
import com.aimluck.eip.common.ALEipPost;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.fileupload.beans.FileuploadLiteBean;
import com.aimluck.eip.fileupload.util.FileuploadUtils;
import com.aimluck.eip.mail.ALFolder;
import com.aimluck.eip.mail.ALLocalMailMessage;
import com.aimluck.eip.mail.ALMailFactoryService;
import com.aimluck.eip.mail.ALMailHandler;
import com.aimluck.eip.mail.ALMailSenderContext;
import com.aimluck.eip.mail.ALSmtpMailContext;
import com.aimluck.eip.mail.ALSmtpMailSender;
import com.aimluck.eip.mail.file.ALFileSmtpMailSender;
import com.aimluck.eip.mail.util.ALMailUtils;
import com.aimluck.eip.mail.util.CSVParser;
import com.aimluck.eip.modules.actions.common.ALAction;
import com.aimluck.eip.orm.Database;
import com.aimluck.eip.orm.query.Operations;
import com.aimluck.eip.orm.query.SQLTemplate;
import com.aimluck.eip.orm.query.SelectQuery;
import com.aimluck.eip.services.storage.ALStorageService;
import com.aimluck.eip.user.beans.UserGroupPositionLiteBean;
import com.aimluck.eip.user.beans.UserLiteBean;
import com.aimluck.eip.user.util.UserUtils;
import com.aimluck.eip.util.ALEipUtils;
import com.aimluck.eip.webmail.beans.WebMailFolderVolumeSummaryBean;
import com.aimluck.eip.webmail.beans.WebmailAccountLiteBean;
import com.aimluck.eip.webmail.beans.WebmailHiddenDataBean;
import com.aimluck.eip.webmail.util.WebMailUtils;
import com.sk_jp.mail.MailUtility;

/**
 * Webメールフォームデータを管理するためのクラスです。 <br />
 */
public class WebMailFormData
// change start
    // 運用課題No.68
    // extends ALAbstractFormData {
    extends ALAbstractFormWindow {
  // change end

  private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(WebMailFormData.class.getName());

  /** 件名の最大文字数 */
  private final int FIELD_SUBJECT_MAX_LEN = 256;

  /** 宛先（To，CC，BCC）の最大文字数 */
  private final int FIELD_RECIPIENT_MAX_LEN = 512;

  /** メール本文の最大文字数 */
  private final int FIELD_BODY_MAX_LEN = 50000;

  /** タイプ：デフォルトメール */
  public static final int TYPE_DEF_MAIL = -1;

  /** タイプ：新規メール */
  public static final int TYPE_NEW_MAIL = 0;

  /** タイプ：返信メール */
  public static final int TYPE_REPLY_MAIL = 1;

  /** タイプ：転送メール */
  public static final int TYPE_FORWARD_MAIL = 2;

  /** タイプ：全員に返信メール */
  public static final int TYPE_REPLY_ALL_MAIL = 3;

  // add start
  /** タイプ：編集 */
  public static final int TYPE_EDIT_MAIL = 4;

  /** タイプ：下書き */
  public static final int TYPE_DRAFT_MAIL = 5;

  /** 下書き保存 */
  public static final int SAVE_DRAFT = 1;

  /** 代理送信フォーム */
  public static final String REPRESENT_SEND = "1";

  // add end

  /** メール作成のタイプ */
  private ALNumberField mailType = null;

  /** 宛名 */
  private ALStringField to = null;

  /** CC */
  private ALStringField cc = null;

  /** BCC */
  private ALStringField bcc = null;

  /** 件名 */
  private ALStringField subject = null;

  /** 本文 */
  private ALStringField body = null;

  /** 添付ファイルリスト */
  private List<FileuploadLiteBean> fileuploadList = null;

  private String folderName = null;

  /**  */
  private int userId = -1;

  /**  */
  private int accountId = -1;

  private String orgId;

  // add start
  /** 開封確認 */
  private ALStringField hasDispositionNotification;

  /** 送信元アカウントID */
  private ALNumberField fromAccountId;

  /** 代理送信元アカウントリスト */
  private List<WebmailAccountLiteBean> mailAccountList;

  /** ログインユーザーのデフォルトアカウント情報 */
  private EipMMailAccount defaultAccount;

  /** 返信/転送時の元メールのID */
  private String orgMailId;

  /** HIDDENパラメータのプレフィックス */
  private static final String PREFIX_COPR_ADDRESS = "u";

  /** HIDDENパラメータのプレフィックス */
  private static final String PREFIX_EXT_ADDRESS = "p";

  // add end

  // remove start 代理送信対応
  // // ログインユーザーの所属する部署2
  // private String current_group_name;
  //
  // // ログインユーザーの所属する部署1
  // private String current_parent_group_name;

  // remove end

  // add start
  /** TO(参照入力宛先表示名) */
  private ALStringField toNames;

  /** CC(参照入力宛先表示名) */
  private ALStringField ccNames;

  /** BCC(参照入力宛先表示名) */
  private ALStringField bccNames;

  /** 宛先（グループ送信） */
  private ALStringField toGroupsend;

  /** CC（グループ送信） */
  private ALStringField ccGroupsend;

  /** BCC（グループ送信） */
  private ALStringField bccGroupsend;

  /** 宛先（社内アドレス） */
  private ALStringField toCorp;

  /** CC（社内アドレス） */
  private ALStringField ccCorp;

  /** BCC（社内アドレス） */
  private ALStringField bccCorp;

  /** 宛先（個人アドレス） */
  private ALStringField toExt;

  /** CC（個人アドレス） */
  private ALStringField ccExt;

  /** BCC（個人アドレス） */
  private ALStringField bccExt;

  /** 宛先を引用する */
  private ALStringField quoteTo;

  /** 本文を引用する */
  private ALStringField quoteBody;

  /** 本文に引用符を付ける */
  private ALStringField addQuotationMarks;

  /** 代理受信フラグ */
  private boolean isRepresent;

  private String saveMode;

  private boolean isCellularSmartPhone = false;

  /** 現在選択されているタブ (＝受信メール or 送信メール) 受入テスト障害168 */
  private String currentTab;

  /** （携帯・ｽﾏｰﾄﾌｫﾝ）宛先（グループ送信）表示名 */
  private String toGroupsendName;

  /** （携帯・ｽﾏｰﾄﾌｫﾝ）CC（グループ送信）表示名 */
  private String ccGroupsendName;

  /** （携帯・ｽﾏｰﾄﾌｫﾝ）BCC（グループ送信）表示名 */
  private String bccGroupsendName;

  /** 下書きFrom代理送信フラグ */
  private boolean isDraftAccount = false;

  /** 下書きFrom代理送信アカウントId */
  private String draftAccountId = null;

  /** 代理送信フォームフラグ 代理送信の場合は"1" */
  private String representSend;

  // add end

  // add start 2012.1.19 簡体字中国語対応
  /** 送信文字コード */
  private ALStringField sendCharcode;

  // add end

  // add start 2012.2.3
  // 中国語対応による下書き時のタイプ
  private boolean isCharcodeChinese = false;

  // add end

  @Override
  public void init(ALAction action, RunData rundata, Context context) throws ALPageNotFoundException, ALDBErrorException {
    super.init(action, rundata, context);

    userId = ALEipUtils.getUserId(rundata);
    try {
      accountId = Integer.parseInt(ALEipUtils.getTemp(rundata, context, WebMailUtils.ACCOUNT_ID));
    } catch (Exception e) {
      accountId = 0;
    }

    // add start 運用フェーズ課題・障害台帳No.１５０
    String ownerAccountId = rundata.getParameters().getString("ownerAccountId", "");
    if (!"".equals(ownerAccountId)) {
      try {
        accountId = Integer.parseInt(ownerAccountId);
      } catch (Exception e) {
        accountId = 0;
      }
    }
    // add end

    // add start
    // ログインユーザーのデフォルトアカウント取得
    // ポートレット設定よりデフォルトアカウントIDを取得
    String defaultAccountId = ALEipUtils.getPortlet(rundata, context).getPortletConfig().getInitParameter("p3a-accounts");
    if (null != defaultAccountId && defaultAccountId.length() > 0) {
      // ポートレット設定より取得できた場合
      defaultAccount = ALMailUtils.getMailAccount(userId, Integer.parseInt(defaultAccountId));
    } else {
      // ポートレット設定より取得できなかった場合、ユーザーの全アカウントの中で最初に検索されたアカウントとする
      // remove start
      // defaultAccountId =
      // WebMailUtils
      // .getMailAccountNameList(userId)
      // .get(0)
      // .getAccountId()
      // .toString();
      // remove end
      try {
        // defaultAccount =
        // WebMailUtils.getMailAccount(Integer.parseInt(defaultAccountId));
        defaultAccount = WebMailUtils.getDefaultMailAccount(userId);
      } catch (Exception e) {
        logger.error("デフォルトアカウントの取得に失敗しました。 " + ALEipUtils.getUserFullName(userId));
        throw new ALPageNotFoundException();
      }

    }

    folderName = rundata.getParameters().getString("folderName");

    orgId = Database.getDomainName();

    // // add by motegi start 代理送信対応
    // // 現在のユーザー名を取得する
    // ALEipUser loginuser = ALEipUtils.getALEipUser(rundata);
    // // ログインユーザーの所属部署1,部署2を取得する
    // List<UserGroupPositionLiteBean> list =
    // UserUtils.getPostPositionBeanList((int)
    // loginuser.getUserId().getValue());
    // if (list != null && list.size() > 0) {
    // UserGroupPositionLiteBean b = list.get(0);
    // current_parent_group_name = b.getPost1GroupName();
    // current_group_name = b.getPost2GroupName();
    // }
    // // add end

    // add start
    // 代理受信フラグ設定（代理受信の返信、転送時）
    isRepresent = false;
    if (rundata.getParameters().containsKey("represent")) {
      isRepresent = (rundata.getParameters().getString("represent").equals("true"));
    }
    // add end

    // add start
    // 下書きフラグ取得
    saveMode = rundata.getParameters().getString("saveMode");

    // 代理送信フラグ取得
    representSend = rundata.getParameters().getString("representSend");

    // add start 2011.1202 受入テスト障害168
    // 現在選択されているタブ（受信トレイor送信トレイ）
    if (rundata.getParameters().containsKey(ALEipConstants.ENTITY_ID)
      && !"new".equals(rundata.getParameters().getString(ALEipConstants.ENTITY_ID))
      && !"".equals(rundata.getParameters().getString(ALEipConstants.ENTITY_ID))) {
      String tabParam = rundata.getParameters().getString("tab");
      if (tabParam == null || "".equals(tabParam)) {
        if (isCellularSmartPhone) {
          tabParam = ALEipUtils.getTemp(rundata, context, "tab");
        } else {
          throw new ALDBErrorException();
        }
      }
      if (WebMailUtils.TAB_SENT.equals(tabParam)) {
        currentTab = WebMailUtils.TAB_SENT;
      } else {
        currentTab = WebMailUtils.TAB_RECEIVE;
      }
    }

    // （携帯・ｽﾏｰﾄﾌｫﾝ）宛先（グループ送信）表示名 */
    toGroupsendName = rundata.getParameters().getString("toGroupsendName");
    // （携帯・ｽﾏｰﾄﾌｫﾝ）CC（グループ送信）表示名 */
    ccGroupsendName = rundata.getParameters().getString("ccGroupsendName");
    // （携帯・ｽﾏｰﾄﾌｫﾝ）BCC（グループ送信）表示名 */
    bccGroupsendName = rundata.getParameters().getString("bccGroupsendName");
    // add end
  }

  /**
   * 
   */
  @Override
  public void initField() {
    // メール作成のタイプ
    mailType = new ALNumberField();
    mailType.setFieldName("タイプ");

    // To
    to = new ALStringField();
    to.setFieldName("宛先");
    to.setTrim(true);

    // CC
    cc = new ALStringField();
    cc.setFieldName("CC");
    cc.setTrim(true);

    // BCC
    bcc = new ALStringField();
    bcc.setFieldName("BCC");
    bcc.setTrim(true);

    // Subject
    subject = new ALStringField();
    subject.setFieldName("件名");
    subject.setTrim(true);

    // Body
    body = new ALStringField();
    body.setFieldName("本文");
    body.setTrim(false);

    fileuploadList = new ArrayList<FileuploadLiteBean>();

    // add start
    hasDispositionNotification = new ALStringField();
    hasDispositionNotification.setFieldName("開封確認");
    hasDispositionNotification.setTrim(true);

    // 送信元アカウントID
    fromAccountId = new ALNumberField();
    fromAccountId.setFieldName("送信元");

    toNames = new ALStringField();
    toNames.setFieldName("TO(参照入力表示用データ)");

    ccNames = new ALStringField();
    ccNames.setFieldName("CC(参照入力表示用データ)");

    bccNames = new ALStringField();
    bccNames.setFieldName("BCC(参照入力表示用データ)");

    toGroupsend = new ALStringField();
    toGroupsend.setFieldName("宛先（グループ送信）");

    ccGroupsend = new ALStringField();
    ccGroupsend.setFieldName("CC（グループ送信）");

    bccGroupsend = new ALStringField();
    bccGroupsend.setFieldName("BCC（グループ送信）");

    toCorp = new ALStringField();
    toCorp.setFieldName("宛先（社内アドレス）");

    ccCorp = new ALStringField();
    ccCorp.setFieldName("CC（社内アドレス）");

    bccCorp = new ALStringField();
    bccCorp.setFieldName("BCC（社内アドレス）");

    toExt = new ALStringField();
    toExt.setFieldName("宛先（個人アドレス）");

    ccExt = new ALStringField();
    ccExt.setFieldName("CC（個人アドレス）");

    bccExt = new ALStringField();
    bccExt.setFieldName("BCC（個人アドレス）");

    quoteTo = new ALStringField();
    quoteTo.setFieldName("宛先を引用する");

    quoteBody = new ALStringField();
    quoteBody.setFieldName("本文を引用する");

    addQuotationMarks = new ALStringField();
    addQuotationMarks.setFieldName("本文に引用符を付ける");
    // add end

    // add start 2012.1.19 簡体字中国語対応
    /** 送信文字コード */
    sendCharcode = new ALStringField();

    // add end
  }

  /**
   * 各フィールドに対する制約条件を設定する抽象メソッドです。
   */
  @Override
  protected void setValidator() {

    // remove start

    // 宛先を必須項目にする
    // to.setNotNull(true);

    // to.limitMaxLength(FIELD_RECIPIENT_MAX_LEN);

    // CC
    // cc.limitMaxLength(FIELD_RECIPIENT_MAX_LEN);

    // BCC
    // bcc.limitMaxLength(FIELD_RECIPIENT_MAX_LEN);

    // remove end

    // 件名の文字数制限
    subject.limitMaxLength(FIELD_SUBJECT_MAX_LEN);

    // 本文の文字数制限
    body.limitMaxLength(FIELD_BODY_MAX_LEN);

  }

  /**
   * フォームデータの妥当性を検証する．
   * 
   * @param msgList
   *            エラーメッセージのリスト
   */
  @Override
  public boolean validate(List<String> msgList) {
    String delim = ",";
    // add start 2012.2.21 受入障害対応No.288
    if (isCellularSmartPhone) {
      // add end
      if (to.validate(msgList)
      // add start
        && to.getValue().trim().length() > 0
        // add end
        && !WebMailUtils.checkAddressForCellularSmartPhone(to.getValue(), delim)) {
        msgList.add("『 <span class='em'>宛先</span> 』を正しく入力してください。");
      }
      if (cc.validate(msgList) && cc.getValue().trim().length() > 0 && !WebMailUtils.checkAddressForCellularSmartPhone(cc.getValue(), delim)) {
        msgList.add("『 <span class='em'>CC</span> 』を正しく入力してください。");
      }
      if (bcc.validate(msgList) && bcc.getValue().trim().length() > 0 && !WebMailUtils.checkAddressForCellularSmartPhone(bcc.getValue(), delim)) {
        msgList.add("『 <span class='em'>BCC</span> 』を正しく入力してください。");
      }
      // add start 2012.2.21 受入障害対応No.288
    } else {
      // add end
      if (to.validate(msgList)
      // add start
        && to.getValue().trim().length() > 0
        // add end
        && !WebMailUtils.checkAddress(to.getValue(), delim)) {
        msgList.add("『 <span class='em'>宛先</span> 』を正しく入力してください。");
      }
      if (cc.validate(msgList) && cc.getValue().trim().length() > 0 && !WebMailUtils.checkAddress(cc.getValue(), delim)) {
        msgList.add("『 <span class='em'>CC</span> 』を正しく入力してください。");
      }
      if (bcc.validate(msgList) && bcc.getValue().trim().length() > 0 && !WebMailUtils.checkAddress(bcc.getValue(), delim)) {
        msgList.add("『 <span class='em'>BCC</span> 』を正しく入力してください。");
      }
      // add start 2012.2.21 受入障害対応No.288
    }
    // add end
    // add start
    if (SAVE_DRAFT != Integer.parseInt(saveMode)) {
      // 下書きの時はチェックを行なわない

      // TO,CC,BCCのいずれも入力されていない場合
      if (to.getValue().trim().length() == 0
        && toGroupsend.getValue().trim().length() == 0
        && cc.getValue().trim().length() == 0
        && ccGroupsend.getValue().trim().length() == 0
        && bcc.getValue().trim().length() == 0
        && bccGroupsend.getValue().trim().length() == 0
      // remove start 運用障害9 2012.4.25
      // && toCorp.getValue().trim().length() == 0
      // && ccCorp.getValue().trim().length() == 0
      // && bccCorp.getValue().trim().length() == 0
      // && toExt.getValue().trim().length() == 0
      // && ccExt.getValue().trim().length() == 0
      // && bccExt.getValue().trim().length() == 0
      // remove end
      ) {
        msgList.add("『 宛先 』を入力してください。");
      }

      if (REPRESENT_SEND.equals(representSend)) {
        if (fromAccountId.getValue() <= 0) {
          msgList.add("『 代理送信元 』を選択してください。");
        }
      }
    }
    // add end

    subject.validate(msgList);
    body.validate(msgList);
    return (msgList.size() == 0);
  }

  /**
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   */
  @Override
  protected boolean deleteFormData(RunData rundata, Context context, List<String> msgList) {
    try {
      int index;
      try {
        index = Integer.parseInt(ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID));
      } catch (Exception e) {
        return false;
      }

      // remove start 2011.1202 受入テスト障害168
      // String currentTab = ALEipUtils.getTemp(rundata, context, "tab");
      // remove end
      int type_mail = (WebMailUtils.TAB_RECEIVE.equals(currentTab)) ? ALFolder.TYPE_RECEIVE : ALFolder.TYPE_SEND;
      ALMailHandler handler = ALMailFactoryService.getInstance().getMailHandler();
      ALFolder folder = handler.getALFolder(type_mail, orgId, userId, Integer.valueOf(accountId));
      folder.deleteMail(index);
      // change start
      // } catch (Exception e) {
      // Database.rollback();
      // logger.error("Exception", e);
      // return false;
    } catch (Throwable t) {
      Database.rollback();
      String msg = "メールの削除に失敗しました。[" + ALEipUtils.getBaseUser(userId).getUserName() + "]";
      logger.error(msg, t);
      msgList.add(msg);
      return false;
      // change end
    }
    return true;
  }

  /**
   * メール送信処理
   * <p>
   * メールを送信し、DB、ファイルに登録する。<BR>
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return boolean true:処理成功 false:処理失敗
   */
  @Override
  protected boolean insertFormData(RunData rundata, Context context, List<String> msgList) {

    // add start
    try {
      // String save = rundata.getParameters().getString("saveMode");
      String save = saveMode;

      // 通常送信時（下書き保存ではない）、既に最大容量オーバーの場合送信不可とする
      if (SAVE_DRAFT != Integer.parseInt(save)) {

        // ログインユーザーの全アカウントID取得
        List<EipMMailAccount> accountList = WebMailUtils.getMailAccountNameList(ALEipUtils.getUserId(rundata));
        List<Integer> accountIdList = new ArrayList<Integer>();
        for (int i = 0; i < accountList.size(); i++) {
          accountIdList.add(accountList.get(i).getAccountId());
        }
        // ログインユーザーの全フォルダ使用容量率取得
        WebMailFolderVolumeSummaryBean folderVolumeSummaryBean = new WebMailFolderVolumeSummaryBean();
        folderVolumeSummaryBean = WebMailUtils.getFolderVolumeSummaryBean(accountIdList);

        // メールボックス使用率が100%以上の場合
        // change start 受入障害対応No.218
        // if (Integer.parseInt(folderVolumeSummaryBean
        if (Long.parseLong(folderVolumeSummaryBean
        // change end
          .getMailBoxVolumePct()
          .toString()) >= 100) {
          if (rundata.getParameters().containsKey("send_from_mobile")) {
            msgList.add("メールボックスがいっぱいの為メール送信が行えません。PCから「保存する」ボタンで下書きに保存し、メール一覧の「メール退避・削除・移動」より退避、削除を行ってください。 ");
          } else {
            msgList.add("メールボックスがいっぱいの為メール送信が行えません。「保存する」ボタンで下書きに保存し、メール一覧の「メール退避・削除・移動」より退避、削除を行ってください。 ");
          }
          return false;
        }
      }

      String[] attachmentFilepaths = null;
      FileuploadLiteBean filebean = null;
      boolean hasAttachments = (fileuploadList != null && fileuploadList.size() > 0);
      if (hasAttachments) {
        int size = fileuploadList.size();
        attachmentFilepaths = new String[size];
        for (int i = 0; i < size; i++) {
          filebean = fileuploadList.get(i);
          attachmentFilepaths[i] =
            ALStorageService.getDocumentPath(FileuploadUtils.FOLDER_TMP_FOR_ATTACHMENT_FILES, userId + ALStorageService.separator() + folderName)
              + ALStorageService.separator()
              + filebean.getFileId();
        }
      }

      // 件名の値を検証
      if (subject.getValue() == null || subject.getValue().equals("")) {
        subject.setValue("（件名なし）");
      }

      // add start
      // グループ送信に含まれるアドレスを連結する

      // TOの設定
      String orgTo = to.getValue();
      // 運用課題No.98(#351) CSVParserに対応
      orgTo = convertDirectInputDestination(orgTo);
      to.setValue("");

      // // TO 個人アドレス
      // remove start 運用障害9 2012.4.25
      // if (!(null == toExt)) {
      // setAddress(to, toExt.getValue());
      // }
      //
      // // TO 社内アドレス
      // if (!(null == toCorp)) {
      // setAddress(to, toCorp.getValue());
      // }
      // remove end

      if (!(null == toGroupsend)) {
        setGroupSendAddress(rundata, to, toGroupsend.toString());
      }

      // 直接入力アドレスを末尾にする
      if (to.getValue() != null && !"".equals(to.getValue())) {
        if (orgTo != null && !"".equals(orgTo)) {
          to.setValue(to.getValue() + "," + orgTo);
        }
      } else {
        to.setValue(orgTo);
      }

      // System.out.println("TO:" + to.getValue());

      // CCの設定
      String orgCc = cc.getValue();
      // 運用課題No.98(#351) CSVParserに対応
      orgCc = convertDirectInputDestination(orgCc);
      cc.setValue("");

      // // CC 個人アドレス
      // remove start 運用障害9 2012.4.25
      // if (!(null == ccExt)) {
      // setAddress(cc, ccExt.getValue());
      // }
      //
      // // CC 社内アドレス
      // if (!(null == ccCorp)) {
      // setAddress(cc, ccCorp.getValue());
      // }
      // remove end

      // CC グループ送信
      if (!(null == ccGroupsend)) {
        setGroupSendAddress(rundata, cc, ccGroupsend.toString());
      }

      // 直接入力アドレス設定
      if (cc.getValue() != null && !"".equals(cc.getValue())) {
        if (orgCc != null && !"".equals(orgCc)) {
          cc.setValue(cc.getValue() + "," + orgCc);
        }
      } else {
        cc.setValue(orgCc);
      }

      // System.out.println("CC:" + cc.getValue());

      // BCCの設定
      String orgBcc = bcc.getValue();
      // 運用課題No.98(#351) CSVParserに対応
      orgBcc = convertDirectInputDestination(orgBcc);
      bcc.setValue("");

      // // BCC 個人アドレス
      // remove start 運用障害9 2012.4.25
      // if (!(null == bccExt)) {
      // setAddress(bcc, bccExt.getValue());
      // }
      //
      // // BCC 社内アドレス
      // if (!(null == bccCorp)) {
      // setAddress(bcc, bccCorp.getValue());
      // }
      // remove end

      if (!(null == bccGroupsend)) {
        setGroupSendAddress(rundata, bcc, bccGroupsend.toString());
      }

      // 直接入力アドレスを末尾にする
      if (bcc.getValue() != null && !"".equals(bcc.getValue())) {
        if (orgBcc != null && !"".equals(orgBcc)) {
          bcc.setValue(bcc.getValue() + "," + orgBcc);
        }
      } else {
        bcc.setValue(orgBcc);
      }

      // System.out.println("BCC:" + bcc.getValue());

      // add end

      // 返信メールの場合は，ヘッダを追加する．
      // change start 受入テスト障害174, 176 @@Aip会議案内対応
      // Map<String, String> map = null;
      Map<String, String> map = new LinkedHashMap<String, String>();
      // change end
      // change start 受入テスト障害174, 176 @@Aip会議案内対応
      // change start @@Aipo会議案内対応
      // if (getMailType().getValue() == TYPE_REPLY_MAIL
      // || getMailType().getValue() == TYPE_REPLY_ALL_MAIL) {
      if (getMailType().getValue() == TYPE_REPLY_MAIL || getMailType().getValue() == TYPE_REPLY_ALL_MAIL || getMailType().getValue() == TYPE_FORWARD_MAIL) {
        // change end
        ALLocalMailMessage msg = null;
        try {
          msg = (ALLocalMailMessage) WebMailUtils.getSelectedLocalMailMessage(rundata, context, (int) getMailType().getValue(), currentTab /*
                                                                                                                                             * add
                                                                                                                                             * 2011.1203
                                                                                                                                             * 受入テスト障害168
                                                                                                                                             */
          // add start 2012.2.7 受入障害No.272
            ,
            isRepresent
            // add end
            // add start 運用フェーズ課題・障害台帳No.１５０
            ,
            accountId
          // add end
            );
          if (msg == null) {
            return false;
          }
        } catch (Exception e) {
          throw e;
        }
        // add start 受入テスト障害174, 176 @@Aipo会議案内対応
        if (getMailType().getValue() == TYPE_REPLY_MAIL || getMailType().getValue() == TYPE_REPLY_ALL_MAIL) {
          // add end
          String in_reply_tos = msg.getMessageID();
          StringBuffer reference = new StringBuffer();
          String[] references = msg.getHeader("References");
          map = new LinkedHashMap<String, String>();
          if (references != null && references.length > 0) {
            reference.append(ALMailUtils.getOneString(references, " "));
          }
          if (in_reply_tos != null && (!in_reply_tos.equals(""))) {
            map.put("In-Reply-To", in_reply_tos);
            reference.append(" ").append(in_reply_tos);
          }

          if (reference.toString() != null || (!reference.toString().equals(""))) {
            map.put("References", reference.toString());
          }
          // add start 受入テスト障害174, 176 @@Aipo会議案内対応
        }
        // add end

        // add start 受入テスト障害174, 176 @@Aipo会議案内対応
        String[] aipoFlg = msg.getHeader("X-Aipo-Portlet");
        if (aipoFlg != null && aipoFlg.length > 0) {
          map.put("X-Aipo-Portlet", "Schedule");
        }
        // add end @@Aipo会議案内対応
      }

      if (map != null && map.size() == 0) {
        map = null;
      }

      String delim = ",";

      // add start
      boolean representation_transmission = false;

      // 送信元アカウントID
      int inputAccountId = (int) fromAccountId.getValue();

      // change start 受入テスト障害325
      // if (accountId != inputAccountId) {
      // if (!isRepresent) {
      if (REPRESENT_SEND.equals(representSend)) {
        // 代理送信の場合
        // （送信元アカウントIDが処理中のアカウントIDと異なる、代理受信の返信ではない場合）
        representation_transmission = true;
        // }
      }
      // add end

      // アカウント情報を取得
      // change start
      // EipMMailAccount account = ALMailUtils.getMailAccount(userId,
      // accountId);
      EipMMailAccount account = ALMailUtils.getMailAccount(accountId);

      // 代理受信を返信する場合、ログインユーザーのデフォルトアカウントとする
      if (isRepresent) {
        account = defaultAccount;
      }
      // change end

      ALMailHandler handler = ALMailFactoryService.getInstance().getMailHandler();
      // 送信サーバ情報
      ALMailSenderContext scontext = ALMailUtils.getALSmtpMailSenderContext(orgId, account);

      // add start
      // 送信元設定
      String fromAddress = account.getMailAddress();
      String fromName = account.getMailUserName();

      // 代理送信の場合
      if (representation_transmission) {

        if (SAVE_DRAFT != Integer.parseInt(save)) {
          // 代理送信元アカウント情報取得
          EipMMailAccount deputyAccount = ALMailUtils.getMailAccount(inputAccountId);
          // 代理送信時は送信元を代理送信依頼者とする
          fromAddress = deputyAccount.getMailAddress();
          fromName = deputyAccount.getMailUserName();
          // 代理送信元アカウントの部署、役職情報取得
          List<UserGroupPositionLiteBean> userPostPositionList = UserUtils.getPostPositionBeanList(deputyAccount.getUserId());
          UserGroupPositionLiteBean userPostPosition = userPostPositionList.get(0);

          // 代理送信メッセージを本文の上にセット
          StringBuffer deputyMsg = new StringBuffer();
          deputyMsg.append("<").append(account.getMailUserName()).append("> が次の人の代理で送信しました:");
          if (!(null == userPostPosition.getPositionName())) {
            deputyMsg.append(userPostPosition.getPositionName()).append(" ");
          }
          deputyMsg.append(deputyAccount.getMailUserName()).append("\r\n\r\n").append(body.getValue());

          body.setValue(deputyMsg.toString());

        }
        // add start 2011/12/9
        // 下書き保存時はFrom設定がなくても登録できるようにする
        else {
          if (0 != inputAccountId) {
            // 代理送信元アカウント情報取得
            EipMMailAccount deputyAccount = ALMailUtils.getMailAccount(inputAccountId);
            // 代理送信時は送信元を代理送信依頼者とする
            fromAddress = deputyAccount.getMailAddress();
            fromName = deputyAccount.getMailUserName();
          }
        }
        // add end
      }
      // add end

      // change start
      // 送信メッセージのコンテキスト
      // mod by motegi 開封確認
      // ALSmtpMailContext mailcontext =
      // ALMailUtils.getALSmtpMailContext(ALMailUtils.getTokens(ALStringUtil
      // .unsanitizing(to.getValue()), delim), ALMailUtils.getTokens(
      // ALStringUtil.unsanitizing(cc.getValue()),
      // delim), ALMailUtils.getTokens(ALStringUtil.unsanitizing(bcc
      // .getValue()), delim), account.getMailAddress(), ALStringUtil
      // .unsanitizing(account.getMailUserName()), ALStringUtil
      // .unsanitizing(subject.getValue()), ALStringUtil.unsanitizing(body
      // .getValue()), attachmentFilepaths, map);

      // 開封確認
      boolean dn = false;
      if (hasDispositionNotification == null || hasDispositionNotification.getValue() == null) {
        dn = false;
      } else if ("ON".equals(hasDispositionNotification.getValue())) {
        dn = true;
      }

      // add start 2012.1.19 簡体字中国語対応
      boolean isChinese = false;
      if (ALMailUtils.GB18030.equals(sendCharcode.getValue())) {
        isChinese = true;
      }
      // add end
      // change start 2012.2.21 受入障害対応No.288 携帯用にgetTokensExtを使い分ける
      // 送信メッセージのコンテキスト
      // ALSmtpMailContext mailcontext =
      // ALMailUtils.getALSmtpMailContext(ALMailUtils.getTokensExt(ALStringUtil
      // .unsanitizing(to.getValue()), delim), ALMailUtils.getTokensExt(
      // ALStringUtil.unsanitizing(cc.getValue()),
      // delim), ALMailUtils.getTokensExt(ALStringUtil.unsanitizing(bcc
      // .getValue()), delim), fromAddress, ALStringUtil
      // .unsanitizing(fromName), ALStringUtil
      // .unsanitizing(subject.getValue()), ALStringUtil.unsanitizing(body
      // .getValue()), attachmentFilepaths, map, dn, false, isChinese);
      ALSmtpMailContext mailcontext;
      if (isCellularSmartPhone) {
        mailcontext =
          ALMailUtils.getALSmtpMailContext(
            ALMailUtils.getTokensExtForMobile(ALStringUtil.unsanitizing(to.getValue()), delim),
            ALMailUtils.getTokensExtForMobile(ALStringUtil.unsanitizing(cc.getValue()), delim),
            ALMailUtils.getTokensExtForMobile(ALStringUtil.unsanitizing(bcc.getValue()), delim),
            fromAddress,
            ALStringUtil.unsanitizing(fromName),
            ALStringUtil.unsanitizing(subject.getValue()),
            ALStringUtil.unsanitizing(body.getValue()),
            attachmentFilepaths,
            map,
            dn,
            false,
            isChinese);
      } else {
        mailcontext =
          ALMailUtils.getALSmtpMailContext(
            ALMailUtils.getTokensExt(ALStringUtil.unsanitizing(to.getValue()), delim),
            ALMailUtils.getTokensExt(ALStringUtil.unsanitizing(cc.getValue()), delim),
            ALMailUtils.getTokensExt(ALStringUtil.unsanitizing(bcc.getValue()), delim),
            fromAddress,
            ALStringUtil.unsanitizing(fromName),
            ALStringUtil.unsanitizing(subject.getValue()),
            ALStringUtil.unsanitizing(body.getValue()),
            attachmentFilepaths,
            map,
            dn,
            false,
            isChinese);
      }
      // change end 2012.2.21

      // int success_send = handler.send(scontext, mailcontext);
      int success_send = ALSmtpMailSender.SEND_MSG_SUCCESS;
      // change end

      // change start
      // save = rundata.getParameters().getString("saveMode");
      if (SAVE_DRAFT != Integer.parseInt(save)) {
        // 通常送信処理（下書き保存ではない）
        success_send = handler.send(scontext, mailcontext);
      } else {
        // add start 2011.1214 受入テスト障害109
        Map<String, String> draftMap = null;
        draftMap = new LinkedHashMap<String, String>();
        // add start 2012.2.3
        // 中国語対応による下書き時のタイプをヘッダー情報に埋め込む
        if (isChinese) {
          draftMap.put("X-Aipo-Draft-Mail-Charcode-Type", ALMailUtils.CHARSET_GB18030);
        } else {
          draftMap.put("X-Aipo-Draft-Mail-Charcode-Type", ALMailUtils.ISO_2022_JP);
        }
        // add end

        // change start 2012.2.9 受入障害対応No.276

        // 下書き時にメールタイプとIDを埋め込む
        // 既に下書きのヘッダーがある場合は持ち回す
        // ない場合は新規に作るTYPE_NEW_MAIL
        // if (TYPE_NEW_MAIL != getMailType().getValue()) {
        // ALLocalMailMessage msg = null;
        // try {
        // msg =
        // (ALLocalMailMessage) WebMailUtils.getSelectedLocalMailMessage(
        // rundata,
        // context,
        // (int) getMailType().getValue(),
        // currentTab
        // // add start 2012.2.7 受入障害No.272
        // ,
        // isRepresent
        // // add end
        // );
        // } catch (Exception e) {
        // throw e;
        // }
        //
        // if (null == msg.getDraftMailParentId()
        // || "".equals(msg.getDraftMailParentId())) {
        // draftMap.put("X-Aipo-Draft-Mail-Type", String.valueOf(getMailType()
        // .getValue()));
        // draftMap.put("X-Aipo-Draft-Mail-Tub", currentTab);
        // draftMap.put("X-Aipo-Draft-Mail-Parent-Id", orgMailId);
        // } else {
        // draftMap.put("X-Aipo-Draft-Mail-Type", String.valueOf(msg
        // .getDraftMailType()));
        // draftMap.put("X-Aipo-Draft-Mail-Tub", msg.getDraftMailTub());
        // draftMap.put("X-Aipo-Draft-Mail-Parent-Id", msg
        // .getDraftMailParentId());
        // }
        // if (representation_transmission) {
        // // 代理送信の場合
        // // 送信元アドレス初期値設定用追加ヘッダー情報
        // draftMap.put("X-Aipo-Draft", String.valueOf(inputAccountId));
        // }
        // mailcontext.setAdditionalHeaders(draftMap);
        // }
        // // add end

        if (representation_transmission) {
          draftMap.put("X-Aipo-Draft", String.valueOf(inputAccountId));
        }

        if (TYPE_NEW_MAIL == getMailType().getValue()) {
          draftMap.put("X-Aipo-Draft-Mail-Type", String.valueOf(getMailType().getValue()));
          draftMap.put("X-Aipo-Draft-Mail-Tub", currentTab);
          draftMap.put("X-Aipo-Draft-Mail-Parent-Id", orgMailId);
        } else {
          ALLocalMailMessage msg = null;
          try {
            // change start 運用フェーズ課題・障害台帳No.１５０
            // msg = (ALLocalMailMessage)
            // WebMailUtils.getSelectedLocalMailMessage(rundata, context, (int)
            // getMailType().getValue(), currentTab, isRepresent);
            msg =
              (ALLocalMailMessage) WebMailUtils.getSelectedLocalMailMessage(
                rundata,
                context,
                (int) getMailType().getValue(),
                currentTab,
                isRepresent,
                accountId);
            // change end
          } catch (Exception e) {
            logger.error("下書きメールファイルの取得に失敗しました。" + e);
          }
          if (null == msg.getDraftMailParentId() || "".equals(msg.getDraftMailParentId())) {
            draftMap.put("X-Aipo-Draft-Mail-Type", String.valueOf(getMailType().getValue()));
            draftMap.put("X-Aipo-Draft-Mail-Tub", currentTab);
            draftMap.put("X-Aipo-Draft-Mail-Parent-Id", orgMailId);
          } else {
            draftMap.put("X-Aipo-Draft-Mail-Type", String.valueOf(msg.getDraftMailType()));
            draftMap.put("X-Aipo-Draft-Mail-Tub", msg.getDraftMailTub());
            draftMap.put("X-Aipo-Draft-Mail-Parent-Id", msg.getDraftMailParentId());
          }
        }
        mailcontext.setAdditionalHeaders(draftMap);
        // change end2012.2.9 受入障害対応No.276

        // 下書き保存の場合
        // アカウントの下書きフォルダを取得
        EipTMailFolder draft_folder = ALMailUtils.getEipTMailFolderByKindAndType(account, ALMailUtils.FOLDER_KIND_SEND, ALMailUtils.FOLDER_TYPE_DRAFT);
        // 保存処理
        ALSmtpMailSender sender = new ALFileSmtpMailSender(scontext);
        success_send = sender.saveMailNoSend(mailcontext, draft_folder.getFolderId().toString());
        // handler.saveMailWithoutSend(scontext, mailcontext, draft_folder
        // .getFolderId()
        // .toString());
      }
      // change end

      if (success_send == ALSmtpMailSender.SEND_MSG_SUCCESS) {
        if (hasAttachments) {
          // 添付ファイル保存先のフォルダを削除
          ALStorageService.deleteTmpFolder(userId, folderName);
        }
        // add start 2011.1214 受入テスト障害109
        // 返信、転送時は元メールの返信転送区分更新
        String reply_foward = null;
        boolean isDraftMail = false;
        String draftMailTab = "";
        if (SAVE_DRAFT != Integer.parseInt(save)) {
          int draft_mail_type = -1;
          // 下書きメールからの送信の場合はsmtpヘッダからメールタイプを取得
          if (getMailType().getValue() == TYPE_DRAFT_MAIL) {
            ALLocalMailMessage msg = (ALLocalMailMessage) WebMailUtils.getSelectedLocalMailMessage(rundata, context, (int) getMailType().getValue(), currentTab
            // add start 2012.2.7 受入障害No.272
              ,
              isRepresent
              // add end
              // add start 運用フェーズ課題・障害台帳No.１５０
              ,
              accountId
            // add end
              );

            draft_mail_type = msg.getDraftMailType();
            draftMailTab = msg.getDraftMailTub();
            orgMailId = msg.getDraftMailParentId();
            isDraftMail = true;
            // 親IDの存在チェック
            // レコードがない場合は
            // 新規メール扱い
            if ((null == orgMailId || "".equals(orgMailId)) || (null == draftMailTab || "".equals(draftMailTab))) {
              draft_mail_type = TYPE_NEW_MAIL;
            } else {
              if (noMailRecord(orgMailId, draftMailTab)) {
                draft_mail_type = TYPE_NEW_MAIL;
              }
            }

          }
          // add end

          // change start 2011.1214 受入テスト障害109
          // 下書き保存時は返信転送区分更新を行わない
          // if (getMailType().getValue() == TYPE_REPLY_MAIL || getMailType()
          // .getValue() == TYPE_REPLY_ALL_MAIL){
          if ((getMailType().getValue() == TYPE_REPLY_MAIL || getMailType().getValue() == TYPE_REPLY_ALL_MAIL)
            || (draft_mail_type == TYPE_REPLY_MAIL || draft_mail_type == TYPE_REPLY_ALL_MAIL)) {
            // change end
            // 返信
            reply_foward = "R";
          }
          // change start 2011.1214 受入テスト障害109
          // if (getMailType().getValue() == TYPE_FORWARD_MAIL) {
          if (getMailType().getValue() == TYPE_FORWARD_MAIL || draft_mail_type == TYPE_FORWARD_MAIL) {
            // 転送
            reply_foward = "F";
          }
          // add start 2011.1214 受入テスト障害109
        }
        // add end

        // 受入テスト障害109
        // if (null != reply_foward && SAVE_DRAFT != Integer.parseInt(save)) {
        if (null != reply_foward) {

          // 下書きは除外
          // 元のメールID取得
          // String mail_id =
          // ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);
          String mail_id = orgMailId;

          // remove start 2011.1202 受入テスト障害168
          // String currentTab = ALEipUtils.getTemp(rundata, context, "tab");
          // remove end

          // change start 2011.1214 受入テスト障害109
          // if (WebMailUtils.TAB_RECEIVE.equals(currentTab)) {
          // // 受信トレイの場合 受信メールを更新
          // EipTMail mail = ALMailUtils.getEipTMail(mail_id);
          // mail.setReplyForward(reply_foward);
          //
          // } else {
          // // 送信トレイの場合 送信メール更新
          // AvzTMailSend mail = ALMailUtils.getAvzTMailSend(mail_id);
          // mail.setReplyForward(reply_foward);
          // }
          if (isDraftMail) {
            if (WebMailUtils.TAB_RECEIVE.equals(draftMailTab)) {
              // 受信トレイの場合 受信メールを更新
              EipTMail mail = ALMailUtils.getEipTMail(mail_id);

              // change start 要件No.22 代理受信メールの転送・返信
              // 代理受信者が転送・返信したメールに対し、受信者本人のメール一覧画面のステータスアイコンを変更する。
              mail.setReplyForward(reply_foward);

              // 既読フラグが"T"なら既読フラグの更新は行わない。
              // 本人操作の場合はメール作成／編集画面を開いた時に更新済み。
              // 代理受信、会議室ユーザー代理受信の場合、一覧画面から返信、転送する場合は既読フラグが"F"
              // 詳細画面から返信、転送する場合はメール詳細画面を開いた時に更新済み。
              if (!mail.getReadFlg().equals("T")) {
                mail.setReadFlg("T");
              }

              // change start 2012.2.9 受入障害対応No.272 代理受信メールは返信・転送区分の更新を行わない。
              // mail.setReplyForward(reply_foward);
              // if (mail.getUserId() == userId) {
              // mail.setReplyForward(reply_foward);
              // }
              // change end 2012.2.9

              // change end

            } else {
              // 送信トレイの場合 送信メール更新
              AvzTMailSend mail = ALMailUtils.getAvzTMailSend(mail_id);
              mail.setReplyForward(reply_foward);
            }
          } else {
            if (WebMailUtils.TAB_RECEIVE.equals(currentTab)) {
              // 受信トレイの場合 受信メールを更新
              EipTMail mail = ALMailUtils.getEipTMail(mail_id);

              // change start 要件No.22 代理受信メールの転送・返信
              // 代理受信者が転送・返信したメールに対し、受信者本人のメール一覧画面のステータスアイコンを変更する。
              mail.setReplyForward(reply_foward);

              // 既読フラグが"T"なら既読フラグの更新は行わない。
              // （本人操作の場合はメール作成／編集画面を開いた時に、"T"(既読)に更新済み。
              // 代理受信、会議室ユーザー代理受信の場合、詳細画面から返信、転送する場合はメール詳細画面を開いた時に
              // "T"(既読)に更新済みだが、一覧画面から返信、転送する場合は既読フラグが"F"であるため。）
              if (!mail.getReadFlg().equals("T")) {
                mail.setReadFlg("T");
              }

              // change start 2012.2.9 受入障害対応No.272 代理受信メールは返信・転送区分の更新を行わない。
              // mail.setReplyForward(reply_foward);
              // change start 2012.2.24 受入障害No.294
              // if (mail.getUserId() == userId) {
              // String accountUsage =
              // ALMailUtils.getMailAccount(accountId).getAccountUsage();
              // if (mail.getUserId() == userId ||
              // (!ALMailUtils.USER_ACCOUNT.equals(accountUsage))) {
              // change end
              // mail.setReplyForward(reply_foward);
              // }
              // change end 2012.2.9

              // change end

            } else {
              // 送信トレイの場合 送信メール更新
              AvzTMailSend mail = ALMailUtils.getAvzTMailSend(mail_id);
              mail.setReplyForward(reply_foward);
            }
          }
          // change end
        }
        // 下書きを送信または編集した場合、編集元の下書きを削除する
        if (getMailType().getValue() == TYPE_DRAFT_MAIL) {

          // セッションより編集元メールIDを取得
          String mail_id = ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);

          if (!(null == mail_id || mail_id.length() == 0)) {
            // 編集元のメール情報取得
            AvzTMailSend mail = ALMailUtils.getAvzTMailSend(mail_id);

            // アカウントの下書きフォルダ取得
            EipTMailFolder draft_folder = ALMailUtils.getEipTMailFolderByKindAndType(account, ALMailUtils.FOLDER_KIND_SEND, ALMailUtils.FOLDER_TYPE_DRAFT);

            // 編集元のメールのフォルダが下書きフォルダであれば、編集元のメールを削除
            if (mail.getFolderId().intValue() == draft_folder.getFolderId()) {

              ALFolder folder = handler.getALFolder(ALFolder.TYPE_SEND, orgId, userId, Integer.valueOf(accountId));
              // 編集元メール削除、フォルダ容量更新してコミット
              try {
                deleteDraftMail(folder, account, Integer.parseInt(mail_id));
              } catch (Throwable t) {
                Database.rollback();
                String msg = "メール送信　下書きメールの削除に失敗しました。[" + ALEipUtils.getBaseUser(userId).getUserName() + "]";
                logger.error(msg, t);
                msgList.add(msg);
                return false;
              }
            }
          }
        }
        // add end

        Database.commit();

      } else {
        if (success_send == ALSmtpMailSender.SEND_MSG_FAIL) {
          msgList.add("メールを送信できませんでした。アカウント設定が間違っている可能性があります。");
        } else if (success_send == ALSmtpMailSender.SEND_MSG_OVER_MAIL_MAX_SIZE) {
          msgList.add("7MB を超えるサイズのメールは送信できません。");
        } else if (success_send == ALSmtpMailSender.SEND_MSG_FAIL_SMTP_AUTH) {
          msgList.add("メールを送信できませんでした。SMTP認証の認証に失敗しました。");
        } else if (success_send == ALSmtpMailSender.SEND_MSG_FAIL_USERUNKNOWN) {
          msgList.add("メールを送信できませんでした。宛先アドレスが誤っている可能性があります。");
        } else if (success_send == ALSmtpMailSender.SEND_MSG_FAIL_HOSTUNKNOWN) {
          msgList.add("メールを送信できませんでした。メールサーバーと接続できませんでした。");
        }

        return false;
      }
    } catch (AddressException e) {
      Database.rollback();
      String msg = "個人アドレスにメールアドレスが設定されていません。";
      logger.error(msg + "[" + ALEipUtils.getBaseUser(userId).getUserName() + "]", e);
      msgList.add(msg);
      return false;
    } catch (Exception e) {
      Database.rollback();
      // change start
      // logger.error("Exception", e);
      // msgList.add("メールを送信できませんでした。アカウント設定が間違っている可能性があります。");
      String msg = "メールを送信できませんでした。[" + ALEipUtils.getBaseUser(userId).getUserName() + "]";
      logger.error(msg, e);
      msgList.add(msg);
      // change end
      return false;
      // add start
    } catch (Throwable t) {
      Database.rollback();
      String msg = "メールを送信できませんでした。[" + ALEipUtils.getBaseUser(userId).getUserName() + "]";
      logger.error(msg, t);
      msgList.add(msg);
      return false;
      // add end
    }
    return true;
  }

  /**
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @throws ALDBErrorException
   */
  @Override
  protected boolean loadFormData(RunData rundata, Context context, List<String> msgList) throws ALDBErrorException {

    try {
      ALLocalMailMessage msg = (ALLocalMailMessage) WebMailUtils.getSelectedLocalMailMessage(rundata, context, (int) getMailType().getValue(), currentTab /*
                                                                                                                                                           * add
                                                                                                                                                           * 2011.1203
                                                                                                                                                           * 受入テスト障害168
                                                                                                                                                           */
      // add start 2012.2.7 受入障害No.272
        ,
        isRepresent
        // add end
        // add start 運用フェーズ課題・障害台帳No.１５０
        ,
        accountId
      // add end
        );
      if (msg == null) {
        // add start 2012.2.27 受入障害対応No.294
        // ログ出力処理追加
        String tabParam = rundata.getParameters().getString("tab");
        logger.error("メール作成フォーム画面表示用に取得したメッセージオブジェクトがNULLです。メール種別タブ: "
          + rundata.getParameters().getInt(WebMailUtils.MAIL_TYPE, TYPE_NEW_MAIL)
          + "メールID: "
          + ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID)
          + " currentTub:"
          + tabParam);
        // add end end

        msgList.add("返信／転送／編集元のメール情報の取得に失敗しました。操作をもう一度やりなおして下さい。");
        return false;
      }

      // add start
      // 別ウインドウ化対応 ウインドウにエンティティIDを渡すため
      setEntityId(ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID));
      // add end

      mailType.setValue(rundata.getParameters().getInt(WebMailUtils.MAIL_TYPE, TYPE_NEW_MAIL));

      String tmpSubject = null;
      if (getMailType().getValue() == TYPE_NEW_MAIL) {
        // TO
        Address[] tos = msg.getRecipients(Message.RecipientType.TO);
        this.setTo(ALMailUtils.getAddressString(tos));

        // CC
        Address[] ccs = msg.getRecipients(Message.RecipientType.CC);
        this.setCc(ALMailUtils.getAddressString(ccs));
        // BCC
        Address[] bccs = msg.getRecipients(Message.RecipientType.BCC);
        this.setBcc(ALMailUtils.getAddressString(bccs));
        // change start 2011/12/20 IBM拡張文字対応
        // tmpSubject = msg.getSubject();
        tmpSubject = ALMailUtils.decodeSubject(msg.getHeader("Subject", null));
        // change end
      } else if (getMailType().getValue() == TYPE_REPLY_MAIL) {
        // TO
        Address[] tos = msg.getFrom();

        // add start
        if (!isCellularSmartPhone) {
          // change start 運用障害9 2012.4.25
          // tos = convertMailAddress2Name(tos, toNames, toCorp, toExt);
          tos = convertMailAddress2Name(tos, toNames, toGroupsend);
          // change end
        }
        // add end

        this.setTo(ALMailUtils.getAddressString(tos));

        // change start 2011/12/20 IBM拡張文字対応
        // tmpSubject = "Re: " + msg.getSubject();
        tmpSubject = "Re: " + ALMailUtils.decodeSubject(msg.getHeader("Subject", null));
        // change end
      } else if (getMailType().getValue() == TYPE_FORWARD_MAIL) {
        // change start 2011/12/20 IBM拡張文字対応
        // tmpSubject = "Fwd: " + msg.getSubject();
        tmpSubject = "Fwd: " + ALMailUtils.decodeSubject(msg.getHeader("Subject", null));
        // change end
      } else if (getMailType().getValue() == TYPE_REPLY_ALL_MAIL) {
        // add start
        // 自分のアドレスを除くために使用するアカウントを取得
        EipMMailAccount accountforRemoveAddress = ALMailUtils.getMailAccount(accountId);
        // add end

        // TO
        Address[] from = msg.getFrom();
        Address[] to = msg.getRecipients(Message.RecipientType.TO);

        // add start by motegi 自分のアドレスは除く
        to = WebMailUtils.removeMyAddress(to, accountforRemoveAddress.getMailAddress());
        // add end
        int from_length = from.length;
        int to_length = to.length;
        Address[] tos = new Address[from_length + to_length];
        for (int i = 0; i < from_length; i++) {
          tos[i] = from[i];
        }
        for (int i = 0; i < to_length; i++) {
          tos[i + from_length] = to[i];
        }

        // add start
        // change start 運用障害9 2012.4.25
        // tos = convertMailAddress2Name(tos, toNames, toCorp, toExt);
        tos = convertMailAddress2Name(tos, toNames, toGroupsend);
        // change end
        // add end

        this.setTo(ALMailUtils.getAddressString(tos));

        // CC
        Address[] ccs = msg.getRecipients(Message.RecipientType.CC);
        // add start by motegi 自分のアドレスは除く
        ccs = WebMailUtils.removeMyAddress(ccs, accountforRemoveAddress.getMailAddress());
        // add end

        // add start
        // change start 運用障害9 2012.4.25
        // ccs = convertMailAddress2Name(ccs, ccNames, ccCorp, ccExt);
        ccs = convertMailAddress2Name(ccs, ccNames, ccGroupsend);
        // add end
        // change end

        this.setCc(ALMailUtils.getAddressString(ccs));

        // BCC
        Address[] bccs = msg.getRecipients(Message.RecipientType.BCC);
        // add start by motegi 自分のアドレスは除く
        bccs = WebMailUtils.removeMyAddress(bccs, accountforRemoveAddress.getMailAddress());
        // add end

        // add start
        // change start 運用障害9 2012.4.25
        // bccs = convertMailAddress2Name(bccs, bccNames, bccCorp, bccExt);
        bccs = convertMailAddress2Name(bccs, bccNames, bccGroupsend);
        // add end
        // change end

        this.setBcc(ALMailUtils.getAddressString(bccs));

        // change start 2011/12/20 IBM拡張文字対応
        // tmpSubject = "Re: " + msg.getSubject();
        tmpSubject = "Re: " + ALMailUtils.decodeSubject(msg.getHeader("Subject", null));
        // change end

        // add start
        // 編集の場合
      } else if (getMailType().getValue() == TYPE_EDIT_MAIL) {
        // 宛先を引用する場合
        quoteTo.setValue(rundata.getParameters().getString("quoteTo"));
        if ("true".equals(quoteTo.getValue())) {
          // TO
          Address[] to = msg.getRecipients(Message.RecipientType.TO);

          // add start
          // change start 運用障害9 2012.4.25
          // to = convertMailAddress2Name(to, toNames, toCorp, toExt);
          to = convertMailAddress2Name(to, toNames, toGroupsend);
          // add end
          // change end

          this.setTo(ALMailUtils.getAddressString(to));

          // CC
          Address[] ccs = msg.getRecipients(Message.RecipientType.CC);

          // add start
          // change start 運用障害9 2012.4.25
          // ccs = convertMailAddress2Name(ccs, ccNames, ccCorp, ccExt);
          ccs = convertMailAddress2Name(ccs, ccNames, ccGroupsend);
          // add end
          // chaneg end

          this.setCc(ALMailUtils.getAddressString(ccs));

          // BCC
          Address[] bccs = msg.getRecipients(Message.RecipientType.BCC);

          // add start
          // change start 運用障害9 2012.4.25
          // bccs = convertMailAddress2Name(bccs, bccNames, bccCorp, bccExt);
          bccs = convertMailAddress2Name(bccs, bccNames, bccGroupsend);
          // add end
          // chaneg end

          this.setBcc(ALMailUtils.getAddressString(bccs));
        }
        // 件名
        // change start 2011/12/20 IBM拡張文字対応
        // tmpSubject = msg.getSubject();
        tmpSubject = ALMailUtils.decodeSubject(msg.getHeader("Subject", null));
        // change end

      } else if (getMailType().getValue() == TYPE_DRAFT_MAIL) {
        // 宛先を引用する場合
        // TO
        Address[] to = msg.getRecipients(Message.RecipientType.TO);

        // add start
        // change start 運用障害9 2012.4.25
        // to = convertMailAddress2Name(to, toNames, toCorp, toExt);
        to = convertMailAddress2Name(to, toNames, toGroupsend);
        // add end
        // chaneg end

        this.setTo(ALMailUtils.getAddressString(to));

        // CC
        Address[] ccs = msg.getRecipients(Message.RecipientType.CC);

        // add start
        // change start 運用障害9 2012.4.25
        // ccs = convertMailAddress2Name(ccs, ccNames, ccCorp, ccExt);
        ccs = convertMailAddress2Name(ccs, ccNames, ccGroupsend);
        // add end
        // chaneg end

        this.setCc(ALMailUtils.getAddressString(ccs));

        // BCC
        Address[] bccs = msg.getRecipients(Message.RecipientType.BCC);

        // add start
        // change start 運用障害9 2012.4.25
        // bccs = convertMailAddress2Name(bccs, bccNames, bccCorp, bccExt);
        bccs = convertMailAddress2Name(bccs, bccNames, bccGroupsend);
        // add end
        // chaneg end

        this.setBcc(ALMailUtils.getAddressString(bccs));
        // 件名
        // change start 2011/12/20 IBM拡張文字対応
        // tmpSubject = msg.getSubject();
        tmpSubject = ALMailUtils.decodeSubject(msg.getHeader("Subject", null));
        // change end
        // add end

        // add start 2011/12/8
        // 開封確認要求付きメッセージなのかどうか判断して、要求があればここでチェック状態にする
        String str = msg.getDispositionNotificationTo();
        if (str != null) {
          hasDispositionNotification.setValue("ON");
        }

        // 下書きメールの送信元が代理送信であれば
        // 代理送信フラグと代理送信アカウントIDを設定する
        String strDraftAccountId = msg.getDraftAccountId();
        if (!(null == strDraftAccountId || "".equals(strDraftAccountId))) {
          isDraftAccount = true;
          setDraftAccountId(strDraftAccountId);
        }
        // add end

        // add start 2012.2.3
        // 中国語対応による下書き時のタイプをヘッダー情報から呼び込む
        String CharcodeType = msg.getHeader("X-Aipo-Draft-Mail-Charcode-Type", null);
        if (null != CharcodeType && ALMailUtils.CHARSET_GB18030.equals(CharcodeType)) {
          isCharcodeChinese = true;
        }
      }

      // Subject
      this.setSubject(tmpSubject);

      // 返信の原文付与
      String[] tmp2 = msg.getBodyTextArray();

      // 受入テスト障害174, 176 @@Aip会議案内対応
      String[] aipoFlg = msg.getHeader("X-Aipo-Portlet");
      if (aipoFlg != null && aipoFlg.length > 0) {

        // add start
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);

        // リクエストURLを取得
        String myUrl = jsLink.getPortletById(rundata.getParameters().getString(JetspeedResources.PATH_PORTLETID_KEY)).toString();

        // 現通信がHTTPかHTTPSかを判別
        boolean isSSL = false;
        if (myUrl != null && myUrl.startsWith("https:")) {
          isSSL = true;
        }

        // ポートレット ID を取得する．
        // String portletId = ((JetspeedRunData) rundata).getJs_peid();
        CapabilityMap cm = CapabilityMapFactory.getCapabilityMap(rundata.getRequest().getHeader("User-Agent"));
        MediaTypeEntry media = (MediaTypeEntry) Registry.getEntry(Registry.MEDIA_TYPE, cm.getPreferredMediaType());
        String mediatype = media.getName();

        // List<String>
        List<String> tmpList = new ArrayList<String>();
        for (int i = 0; i < tmp2.length; i++) {
          String s = tmp2[i];
          s = ALMailUtils.replaceStrToLink(s, true, isSSL, myUrl, mediatype, false);
          if (s != null) {
            tmpList.add(s);
          }
        }
        tmp2 = tmpList.toArray(new String[tmpList.size()]);
      }
      // add end @@Aip会議案内対応

      StringBuffer replies = new StringBuffer();

      // add start
      // 返信、全員に返信、転送の場合
      if (getMailType().getValue() == TYPE_REPLY_MAIL || getMailType().getValue() == TYPE_FORWARD_MAIL || getMailType().getValue() == TYPE_REPLY_ALL_MAIL) {
        // add end

        replies.append("\r\n\r\n\r\n" + "------Original Message-------\r\n");

        // add start
        replies.append("From: " + ALMailUtils.getAddressString(msg.getFrom()) + "\r\n");
        replies.append("Sent: " + msg.getSentDate() + "\r\n");
        replies.append("To: " + ALMailUtils.getAddressString(msg.getRecipients(Message.RecipientType.TO)) + "\r\n");
        // add start 運用フェーズ障害 No.8 2012.4.25
        String referCc = ALMailUtils.getAddressString(msg.getRecipients(Message.RecipientType.CC));
        if (referCc != null && !"".equals(referCc)) {
          replies.append("Cc: " + referCc + "\r\n");
        }
        // add end
        replies.append("Subject: "
        // change start 2011/12/20 IBM拡張文字対応
          // + ALMailUtils.decodeSubject(msg.getSubject())
          + ALMailUtils.decodeSubject(msg.getHeader("Subject", null))
          + "\r\n");
        // change end

        for (String factor : tmp2) {
          replies.append("> " + factor + "\r\n");
        }

      }

      // add start
      if (getMailType().getValue() == TYPE_REPLY_MAIL || getMailType().getValue() == TYPE_FORWARD_MAIL) {
        // add start 受入テスト障害168
        // 開封確認要求付きメッセージなのかどうか判断して、要求があればここで返信
        String str = msg.getDispositionNotificationTo();
        if (str != null && !msg.isNotificationFlg() && WebMailUtils.TAB_RECEIVE.equals(currentTab)) {

          int replyAccountid = accountId;
          int representAccountid = 0;
          if (isRepresent) {
            replyAccountid = defaultAccount.getAccountId();
            representAccountid = accountId;
          }

          WebMailUtils.sendReplyForDispositionNotification(str, msg, userId, replyAccountid, representAccountid, orgId);
          // 開封確認送信済みフラグ更新
          EipTMail email = ALMailUtils.getEipTMail(Integer.toString(msg.getMailId()));
          email.setNotificationFlg("T");
          Database.commit();
        }

      }
      // add end

      // add start
      // 編集の場合
      if (getMailType().getValue() == TYPE_EDIT_MAIL) {
        // 本文を引用する場合
        quoteBody.setValue(rundata.getParameters().get("quoteBody"));
        addQuotationMarks.setValue(rundata.getParameters().getString("addQuotationMarks"));
        // 本文に引用符を付ける場合
        if ("true".equals(addQuotationMarks.getValue())) {
          for (String factor : tmp2) {
            replies.append("> " + factor + "\r\n");
          }
        } else {
          if ("true".equals(quoteBody.getValue())) {
            // 本文に引用符を付けない場合
            // replies.append(msg.getBodyText());
            for (String factor : tmp2) {
              replies.append(factor + "\r\n");
            }
          }
        }
      }

      if (getMailType().getValue() == TYPE_DRAFT_MAIL) {
        // 下書きの場合はそのまま
        replies.append(msg.getBodyText());
      }

      // 本文に付加
      body.setValue(replies.toString());
      // add end

      // add start 20111108、20111124
      // 下書き、もしくは本文引用の場合は署名を付与しない
      if (getMailType().getValue() != TYPE_DRAFT_MAIL && !(getMailType().getValue() == TYPE_EDIT_MAIL && "true".equals(quoteBody.getValue()))) {
        // add end 20111108

        // Body
        try {
          // オブジェクトモデルを取得
          EipMMailAccount account = ALMailUtils.getMailAccount(userId, accountId);
          // 署名と返信とを本文に追加
          if (account.getSignature() != null && !"".equals(account.getSignature())) {

            if (getMailType().getValue() == TYPE_FORWARD_MAIL || getMailType().getValue() == TYPE_REPLY_MAIL || getMailType().getValue() == TYPE_REPLY_ALL_MAIL) {
              body.setValue("\r\n\r\n\r\n\r\n\r\n" + account.getSignature() + replies);
            } else {
              body.setValue(replies + "\r\n\r\n\r\n" + account.getSignature());
            }
          } else {
            body.setValue(replies.toString());
          }
        } catch (Exception ex) {
          logger.error("Exception", ex);
        }
        // add start 20111108
      }
      // add end 20111108

      // add start 要件No.11 メール作成／詳細（ファイル添付）
      // フォルダ名を作成
      if (folderName == null || "".equals(folderName)) {
        folderName = "0_" + String.valueOf(System.nanoTime());
      }
      // add end
      // change 1line start 下書きも添付ファイルをつける
      // if (getMailType().getValue() == TYPE_FORWARD_MAIL) {
      if (getMailType().getValue() == TYPE_FORWARD_MAIL || getMailType().getValue() == TYPE_DRAFT_MAIL) {
        String[] filenames = msg.getAttachmentFileNameArray();

        if (filenames != null && filenames.length > 0) {
          /** 添付ファイルを含んだメールを転送する */
          if (folderName == null || folderName.equals("")) {
            folderName = "undefined";
          }

          for (int i = 0; i < filenames.length; i++) {
            /** 各々の添付ファイルを、一度ファイルに書き出して再度添付する */
            int fileId = Long.valueOf(System.nanoTime()).intValue();
            String newAttachmentFileName = String.valueOf(fileId);
            String realfilename = filenames[i];

            // add start 追加カスタマイズ(添付ファイルサイズ表示)

            // 添付ファイル実サイズ(バイト)
            InputStream in = msg.getInputStream(i);
            int fileSize = getBytes(in).length;
            // 添付ファイルサイズ表示用
            String dispFileSize = "";

            // 表示用ファイルサイズを取得
            dispFileSize = FileuploadUtils.getDispFileSize(fileSize);

            // add end

            ALStorageService.createNewTmpFile(msg.getInputStream(i), userId, folderName, newAttachmentFileName, realfilename);

            // add start 追加カスタマイズ(添付ファイルサイズ表示)
            realfilename = realfilename + dispFileSize;
            // add end

            FileuploadLiteBean filebean = new FileuploadLiteBean();
            filebean.initField();
            filebean.setFileId(fileId);
            filebean.setFileName(realfilename);
            filebean.setFolderName(folderName);
            fileuploadList.add(filebean);
          }
        }
      }
      return true;
    } catch (Exception e) {
      // logger.error("Exception", e);
      // add start
      String msg = "メール作成 初期表示に失敗しました。[" + ALEipUtils.getBaseUser(userId).getUserName() + "]";
      logger.error(msg, e);
      throw new ALDBErrorException();
      // return false;
    } catch (Throwable t) {
      String msg = "メール作成 初期表示に失敗しました。[" + ALEipUtils.getBaseUser(userId).getUserName() + "]";
      logger.error(msg, t);
      throw new ALDBErrorException();
      // add end
    }
  }

  @Override
  protected boolean updateFormData(RunData rundata, Context context, List<String> msgList) throws ALPageNotFoundException, ALDBErrorException {
    return false;
  }

  /**
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @throws ALPageNotFoundException
   * @throws ALDBErrorException
   */
  @Override
  protected boolean setFormData(RunData rundata, Context context, List<String> msgList) throws ALPageNotFoundException, ALDBErrorException {

    boolean res = super.setFormData(rundata, context, msgList);

    if (accountId <= 0 || userId <= 0) {
      return res;
    }
    try {
      // add start 要件No.24 メール添付ファイルタイムアウト対応
      if (!FileuploadUtils.checkFileuploadList(rundata, msgList, "メール")) {
        return false;
      }
      // add end

      fileuploadList = FileuploadUtils.getFileuploadList(rundata);
      // Body
      // オブジェクトモデルを取得
      EipMMailAccount account = ALMailUtils.getMailAccount(userId, accountId);
      // 署名を本文に追加
      if (!ALEipConstants.MODE_INSERT.equals(rundata.getParameters().get(ALEipConstants.MODE))
        && account.getSignature() != null
        && !"".equals(account.getSignature())) {
        StringBuffer bodybuf = new StringBuffer();
        if (body.getValue() != null) {
          bodybuf.append(body.getValue());
        }
        bodybuf.append("\r\n\r\n\r\n");
        bodybuf.append(account.getSignature());
        body.setValue(bodybuf.toString());
      }

      // add start
      int mailType = rundata.getParameters().getInt(WebMailUtils.MAIL_TYPE);
      if (mailType == TYPE_REPLY_MAIL || mailType == TYPE_REPLY_ALL_MAIL || mailType == TYPE_FORWARD_MAIL) {
        orgMailId = rundata.getParameters().getString(ALEipConstants.ENTITY_ID);
        if (orgMailId == null || "".equals(orgMailId)) {
          throw new Exception("返信/転送元メールの情報を取得できませんでした。");
        }
      }
      // add end
      // add start 2012.1.19 簡体字中国語対応
      sendCharcode.setValue(rundata.getParameters().getString("send_charcode"));
      // add end
      // add start 要件No.11 メール作成／詳細（ファイル添付）
      // フォルダ名を作成
      if (folderName == null || "".equals(folderName)) {
        folderName = "0_" + String.valueOf(System.nanoTime());
      }
      // add end

    } catch (Exception ex) {
      // logger.error("Exception", ex);
      // add start
      String msg = "メール情報の取得に失敗しました。";
      logger.error(msg, ex);
      msgList.add(msg);
      return false;
      // add end
    }

    return res;
  }

  /**
   * アカウントの署名文字列を取得します。<BR>
   * 
   * @param account
   *            アカウント情報
   * @return 署名文字列
   */
  private String getSignatureText(EipMMailAccount account) {

    StringBuffer sb = new StringBuffer();
    // 署名が設定されている場合は改行×３を前に付加
    if (account.getSignature() != null && !"".equals(account.getSignature())) {
      sb.append("\r\n\r\n\r\n");
      sb.append(account.getSignature());
    }
    return sb.toString();

  }

  // add start
  /**
   * 編集元の下書きメールを削除する。
   * <p>
   * コミットをここで行わない<br>
   * 
   * @param ALFolder
   *            ローカルフォルダインターフェース
   * @param account
   *            アカウント情報
   * @param mailid
   *            メールID
   * @return true:削除成功 false:削除失敗
   * @throws Throwable
   */
  private boolean deleteDraftMail(ALFolder ALFolder, EipMMailAccount account, int mailid) throws Throwable {
    try {
      String filePath = null;
      String folderId = null;
      Integer fileVolume = 0;

      // 編集元の下書きメール取得
      SelectQuery<AvzTMailSend> query = Database.query(AvzTMailSend.class);
      Expression exp1 = ExpressionFactory.matchDbExp(AvzTMailSend.MAIL_ID_PK_COLUMN, Integer.valueOf(mailid));
      Expression exp2 = ExpressionFactory.matchExp(AvzTMailSend.USER_ID_PROPERTY, userId);
      Expression exp3 = ExpressionFactory.matchExp(AvzTMailSend.ACCOUNT_ID_PROPERTY, accountId);

      AvzTMailSend mail = query.andQualifier(exp1).andQualifier(exp2).andQualifier(exp3).fetchSingle();
      if (null == mail) {
        logger.error("編集元の下書きメールありません。 mail_id=" + mailid);
        throw new ALPageNotFoundException();
      }

      filePath = mail.getFilePath();
      folderId = mail.getFolderId().toString();
      fileVolume = mail.getFileVolume();

      // メールを削除する
      Database.delete(mail);

      // ファイル削除
      ALStorageService.deleteFile(ALFolder.getFullName() + ALStorageService.separator() + filePath);

      // フォルダ容量更新
      EipTMailFolder folder = ALMailUtils.getEipTMailFolder(account, folderId);
      // 削除したメールの容量を差し引く
      folder.setFolderVolume(folder.getFolderVolume() - fileVolume * 1024);

    } catch (Throwable t) {
      throw t;
    }
    return true;
  }

  // add end

  /**
   * @return
   */
  public ALStringField getBcc() {
    return bcc;
  }

  /**
   * @return
   */
  public ALStringField getBody() {
    return body;
  }

  /**
   * @return
   */
  public ALStringField getCc() {
    return cc;
  }

  /**
   * @return
   */
  public ALStringField getSubject() {
    return subject;
  }

  /**
   * @return
   */
  public ALStringField getTo() {
    return to;
  }

  /**
   * @return
   */
  public ALNumberField getMailType() {
    return mailType;
  }

  /**
   * @param field
   */
  public void setMailType(int field) {
    mailType.setValue(field);
  }

  /**
   * @param field
   */
  public void setBcc(String string) {
    bcc.setValue(string);
  }

  /**
   * @param field
   */
  public void setBody(String string) {
    body.setValue(string);
  }

  /**
   * @param field
   */
  public void setCc(String string) {
    cc.setValue(string);
  }

  /**
   * @param field
   */
  public void setSubject(String string) {
    subject.setValue(string);
  }

  /**
   * @param field
   */
  public void setTo(String string) {
    to.setValue(string);
  }

  public String getAccountName() {
    return ALMailUtils.getAccountName(userId, accountId);
  }

  public List<FileuploadLiteBean> getAttachmentFileNameList() {
    return fileuploadList;
  }

  public String getFolderName() {
    return folderName;
  }

  public int getAccountId() {
    return accountId;
  }

  // change start
  // public String getAddrForCell(ALStringField addrs_filed) {
  /**
   * 携帯画面フィールド用 メールアドレス変換処理
   * 
   * @param addrs_filed
   *            変換前メールアドレス
   * @return 変換後メールアドレス
   */
  public static String getAddrForCell(ALStringField addrs_filed) {
    // change end
    if (addrs_filed == null) {
      return "";
    }

    String addrs = addrs_filed.getValue();

    if (addrs == null || addrs.length() == 0) {
      return "";
    }

    StringBuffer addrbuf = new StringBuffer();
    int count = 0;
    String token = null;
    StringTokenizer st = new StringTokenizer(addrs, ",");
    int size = st.countTokens();
    for (int i = 0; i < size; i++) {
      token = st.nextToken();
      if (token.indexOf("<") == -1) {
        addrbuf.append(token);
      } else {
        StringTokenizer tmp_st = new StringTokenizer(token, "<>");
        if (tmp_st.countTokens() == 2) {
          tmp_st.nextToken();
          addrbuf.append(tmp_st.nextToken());
        }
      }
      count = count + 1;
      if (count < size) {
        addrbuf.append(",");
      }
    }
    return addrbuf.toString();
  }

  // add start

  /**
   * グループ送信の所属者のアドレスをカンマ区切りで連結する
   * 
   * @param rundata
   * @param groupsend
   *            メール作成画面で指定されたグループ送信のリスト <br>
   *            [グループ送信ID<空白>グループ送信名],[グループ送信ID<空白>グループ送信名]...
   * @return カンマで連結した全グループ送信の所属者のメールアドレス
   */
  private String connectMailAddress(RunData rundata, String groupsend) {

    if (null == groupsend || "".equals(groupsend)) {
      // return null;
      return "";
    }

    // 全グループ送信のアドレス
    // 指定されたグループ送信に属する全ユーザーのアドレスを連結するためのフィールド
    StringBuffer appendMailAddress = new StringBuffer();

    // 指定されたグループ送信をカンマで分割
    String[] groupsendList = groupsend.split("\n");

    // 分割されたグループ送信の数だけ、所属者のメールアドレスを取得して連結
    List<UserLiteBean> groupsendUserList = null;
    for (int i = 0; i < groupsendList.length; i++) {

      // グループ送信IDより所属者情報を取得する
      groupsendUserList = UserUtils.getUserLiteBeansFromGroup(rundata, groupsendList[i]
      // .split(" ")[0], true);
        .split(" ")[1], true);

      // 所属者の"表示名<メールアドレス>"をカンマ区切りで連結
      StringBuffer groupsendMailAddress = new StringBuffer();
      for (int j = 0; j < groupsendUserList.size(); j++) {
        if (j > 0) {
          groupsendMailAddress.append(",");
        }

        String fullName = groupsendUserList.get(j).getDisplayName().trim();
        // add start 2012.2.7 受入障害対応No.252
        fullName = fullName.replaceAll("\\\\", "\\\\\\\\\\\\\\\\");
        // add end 2012.2.7
        fullName = fullName.replaceAll("\"", "\\\\\\\\\\\\\"");
        String address = null;
        // change start 2012.2.7 受入障害対応No.252
        // if (fullName.indexOf(",") >= 0 || fullName.indexOf("\"") >= 0) {
        if (fullName.indexOf(",") >= 0 || fullName.indexOf("\"") >= 0
        // change start 2012.5.22
          // || fullName.indexOf("\\\\") >= 0) {
          || fullName.indexOf("\\\\") >= 0
          || isWrongAddressesFormat(fullName + "<" + groupsendUserList.get(j).getMailAddress() + ">")) {
          // change end 2012.5.22
          // change end 2012.2.7
          address = "\"" + "\\\"" + fullName + "\\\"" + "<" + groupsendUserList.get(j).getMailAddress() + ">" + "\"";
        } else {
          address = fullName + "<" + groupsendUserList.get(j).getMailAddress() + ">";
        }
        groupsendMailAddress.append(address);
        // groupsendMailAddress.append(groupsendUserList.get(j).getDisplayName()
        // + "<"
        // + groupsendUserList.get(j).getMailAddress()
        // + ">");
      }
      // 全グループ送信のアドレスに連結
      if (!(null == appendMailAddress) && appendMailAddress.length() > 0) {
        appendMailAddress.append(",");
      }
      appendMailAddress.append(groupsendMailAddress);

    }

    return appendMailAddress.toString();

  }

  /**
   * メールアドレス帳で選択したアドレスをカンマ区切りで連結する
   * 
   * @param rundata
   * @param groupsend
   *            メール作成画面で指定されたメールアドレスのリスト <br>
   *            [[u|p]<空白>[ユーザーID|個人アドレスID]<空白>メールアドレス,[[u|p]<空白>[ユーザーID|個人アドレスID]<
   *            空白>メールアドレス,...
   * @return カンマで連結したメールアドレスリスト
   * @throws AddressException
   *             メールアドレスが設定されていない宛先を使用した場合
   */
  // change start 運用障害9 2012.4.25
  // private String connectMailAddressForNormalAddress(String addresses)
  // throws AddressException {
  private String connectMailAddressForNormalAddress(RunData rundata, String addresses) throws AddressException {

    if (null == addresses || "".equals(addresses)) {
      // return null;
      return "";
    }

    // 全グループ送信のアドレス
    // 指定されたグループ送信に属する全ユーザーのアドレスを連結するためのフィールド
    StringBuffer appendMailAddress = new StringBuffer();

    // 指定されたグループ送信をカンマで分割
    String[] mailAddressList = addresses.split("\n");

    // 分割されたグループ送信の数だけ、所属者のメールアドレスを取得して連結
    for (int i = 0; i < mailAddressList.length; i++) {

      String str = mailAddressList[i];
      String[] elements = str.split(" ");
      String address = "";
      // change start 2012.3.15 受入障害対応No.326対応
      if ("".equals(elements) || elements.length < 3) {
        logger.error("メール作成画面で指定されたメールアドレス形式が不正です。 mailAddressList[" + i + "番目]の要素が「" + str + "」で渡されました。[addresses]は " + addresses + " です。");
      }
      // change end
      if (PREFIX_COPR_ADDRESS.equals(elements[0])) {
        String id = elements[1];
        ALBaseUser base = ALEipUtils.getBaseUser(Integer.parseInt(id));
        // System.out.println("[" + base.getDisplayName() + "]");
        if (base.getDisplayName() != null) {
          String fullName = base.getDisplayName().trim();
          // add start 2012.2.7 受入障害対応No.252
          fullName = fullName.replaceAll("\\\\", "\\\\\\\\\\\\\\\\");
          // add end 2012.2.7
          fullName = fullName.replaceAll("\"", "\\\\\\\\\\\\\"");
          // change start 2012.2.7 受入障害対応No.252
          // if (fullName.indexOf(",") >= 0 || fullName.indexOf("\"") >= 0) {
          if (fullName.indexOf(",") >= 0 || fullName.indexOf("\"") >= 0
          // change start 2012.5.22 運用フェーズ課題・障害台帳.xls
            // || fullName.indexOf("\\\\") >= 0) {
            || fullName.indexOf("\\\\") >= 0
            || isWrongAddressesFormat(fullName + "<" + base.getEmail() + ">")) {
            // change end 2012.5.22 運用フェーズ課題・障害台帳.xls
            // change end 2012.2.7
            address = "\"" + "\\\"" + fullName + "\\\"" + "<" + base.getEmail() + ">" + "\"";
          } else {
            address = fullName + "<" + base.getEmail() + ">";
          }
        } else {
          address = "<" + base.getEmail() + ">";
        }
        // change start 運用障害9 2012.4.25
        // } else {
      } else if (PREFIX_EXT_ADDRESS.equals(elements[0])) {
        // change end
        // 個人アドレス処理
        String id = elements[1];
        SelectQuery<EipMAddressbook> query = Database.query(EipMAddressbook.class);
        Expression exp11 = ExpressionFactory.matchDbExp(EipMAddressbook.ADDRESS_ID_PK_COLUMN, Integer.valueOf(id));
        query.setQualifier(exp11);
        EipMAddressbook addr = query.fetchSingle();
        if (addr.getEmail() == null || "".equals(addr.getEmail())) {
          String s = "メールアドレスが設定されていない[" + addr.getLastName() + "]に対してメール送信・下書きが行なわれました";
          logger.error(s);
          throw new AddressException(s);
        }

        String fullName = makeFullName(addr.getLastName(), addr.getFirstName());
        // add start 2012.2.7 受入障害対応No.252
        fullName = fullName.replaceAll("\\\\", "\\\\\\\\\\\\\\\\");
        // add end 2012.2.7
        fullName = fullName.replaceAll("\"", "\\\\\\\\\\\\\"");
        // change start 2012.2.7 受入障害対応No.252
        // if (fullName.indexOf(",") >= 0 || fullName.indexOf("\"") >= 0) {
        if (fullName.indexOf(",") >= 0 || fullName.indexOf("\"") >= 0
        // change start 2012.5.22
          // || fullName.indexOf("\\\\") >= 0) {
          || fullName.indexOf("\\\\") >= 0
          || isWrongAddressesFormat(fullName + "<" + addr.getEmail() + ">")) {
          // change end 2012.5.22
          // change end 2012.2.7 受入障害対応No.252
          address = "\"" + "\\\"" + fullName + "\\\"" + "<" + addr.getEmail() + ">" + "\"";
        } else {
          address = fullName + "<" + addr.getEmail() + ">";
        }

        // address =
        // "\""
        // + "\\\""
        // + makeFullName(addr.getLastName(), addr.getFirstName())
        // + "\\\""
        // + "<"
        // + addr.getEmail()
        // + ">"
        // + "\"";

        // add start 運用障害9 2012.4.25
      } else {
        // グループ送信処理
        String groupsend_id = elements[1];
        // グループ送信IDより所属者情報を取得する
        List<UserLiteBean> groupsendUserList = UserUtils.getUserLiteBeansFromGroup(rundata, groupsend_id, true);

        // 所属者の"表示名<メールアドレス>"をカンマ区切りで連結
        StringBuffer groupsendMailAddress = new StringBuffer();
        for (int j = 0; j < groupsendUserList.size(); j++) {
          if (j > 0) {
            groupsendMailAddress.append(",");
          }

          String fullName = groupsendUserList.get(j).getDisplayName().trim();
          // add start 2012.2.7 受入障害対応No.252
          fullName = fullName.replaceAll("\\\\", "\\\\\\\\\\\\\\\\");
          // add end 2012.2.7
          fullName = fullName.replaceAll("\"", "\\\\\\\\\\\\\"");
          String tmpAddress = null;
          // change start 2012.2.7 受入障害対応No.252
          // if (fullName.indexOf(",") >= 0 || fullName.indexOf("\"") >= 0) {
          if (fullName.indexOf(",") >= 0 || fullName.indexOf("\"") >= 0
          // change start 2012.5.22 運用フェーズ課題・障害台帳.xls
            // || fullName.indexOf("\\\\") >= 0) {
            || fullName.indexOf("\\\\") >= 0
            || isWrongAddressesFormat(fullName + "<" + groupsendUserList.get(j).getMailAddress() + ">")) {
            // change end 2012.5.22 運用フェーズ課題・障害台帳.xls
            // change end 2012.2.7
            tmpAddress = "\"" + "\\\"" + fullName + "\\\"" + "<" + groupsendUserList.get(j).getMailAddress() + ">" + "\"";
          } else {
            tmpAddress = fullName + "<" + groupsendUserList.get(j).getMailAddress() + ">";
          }
          groupsendMailAddress.append(tmpAddress);
        }
        address = groupsendMailAddress.toString();
      }
      // add end

      // アドレスに連結
      if (!(null == appendMailAddress) && appendMailAddress.length() > 0) {
        appendMailAddress.append(",");
      }
      appendMailAddress.append(address);

    }

    return appendMailAddress.toString();

  }

  private String makeFullName(String lastName, String firstName) {
    String str1 = "";
    String str2 = "";

    if (lastName != null) {
      str1 = lastName;
    }

    if (firstName != null) {
      str2 = firstName;
    }

    return (str1 + " " + str2).trim();
  }

  // add end

  /**
   * 
   * @return
   */
  // change start
  // public Map<Integer, ALEipPost> getPostMap() {
  public List<ALEipPost> getPostMap() {

    // 部署階層化対応
    // return ALEipManager.getInstance().getPostMap();
    return ALEipUtils.getPostMap();
    // change end
  }

  /**
   * 処理中のアカウントを返す。<BR>
   * 
   * @return EipMMailAccount アカウント情報
   * @throws Exception
   */
  public EipMMailAccount getDefaultAccount() throws Exception {
    EipMMailAccount selectedAccount = ALMailUtils.getMailAccount(userId, accountId);

    // add start
    if (null == selectedAccount) {
      return defaultAccount;
    } // add end

    return selectedAccount;
  }

  // add start

  /**
   * 開封確認
   * 
   * @return
   */
  public ALStringField getHasDispositionNotification() {
    return hasDispositionNotification;
  }

  /**
   * 代理送信リストの取得
   * <p>
   * 代理送信元のアカウントのリストを返す。<BR>
   * 
   * @return List<WebmailAccountLiteBean> 代理送信元アカウント情報リスト
   * @throws Exception
   */
  public List<WebmailAccountLiteBean> getMailAccountList() throws Exception {
    mailAccountList = new ArrayList<WebmailAccountLiteBean>(0);

    try {
      // ログインユーザーが所属するグループ送信で設定されている代理送信リストを取得
      List<ALEipGroupSend> groupSendList = UserUtils.getGroupSendBeanList(userId);
      List<Integer> groupSendIdList = new ArrayList<Integer>();
      if (!(null == groupSendList) && groupSendList.size() > 0) {
        Iterator<ALEipGroupSend> iterGroupSend = groupSendList.iterator();
        while (iterGroupSend.hasNext()) {
          ALEipGroupSend groupSend = iterGroupSend.next();
          groupSendIdList.add(Integer.parseInt(groupSend.getGroupSendId().toString()));
        }
      }

      StringBuffer sql = new StringBuffer();
      sql.append("SELECT DISTINCT ");
      sql.append(" A.ACCOUNT_ID, B.USER_ID, C.LAST_NAME || ' ' || C.FIRST_NAME ACCOUNT_NAME, C.DISPLAY_NAME, D.POSITION ");
      sql.append(" FROM avz_t_mail_send_recv_acl as A ");
      sql.append(" INNER JOIN eip_m_mail_account as B ");
      sql.append("  on A.ACCOUNT_ID = B.ACCOUNT_ID ");
      sql.append(" INNER JOIN turbine_user as C ");
      sql.append("  on B.USER_ID = C.USER_ID ");
      sql.append(" INNER JOIN eip_m_user_position as D ");
      sql.append(" on B.USER_ID = D.USER_ID ");
      sql.append(" WHERE ");

      // ログインユーザーが所属するグループ送信がある場合の条件
      if (!(null == groupSendIdList) && groupSendIdList.size() > 0) {
        sql.append(" ( ( ");
      }

      sql.append(" A.TARGET_ID = #bind($targetUserId 'INTEGER')  ");
      sql.append(" AND A.TARGET_TYPE = #bind($targetTypeUser 'VARCHAR') ");

      // ログインユーザーが所属するグループ送信がある場合の条件
      if (!(null == groupSendIdList) && groupSendIdList.size() > 0) {
        sql.append(" ) OR ( A.TARGET_ID IN (#bind($targetGroupSendId 'INTEGER')) ");
        sql.append(" AND A.TARGET_TYPE = #bind($targetTypeGroupSend 'VARCHAR') ) ) ");
      }

      sql.append(" AND A.ACL_TYPE = #bind($aclType 'VARCHAR') ");
      sql.append(" ORDER BY C.DISPLAY_NAME, D.POSITION ");

      final String accountSql = sql.toString();

      SQLTemplate<EipMMailAccount> sendAccountQuery = new SQLTemplate<EipMMailAccount>(EipMMailAccount.class, accountSql);

      // 代理送信元アカウントクエリー実行
      List<EipMMailAccount> accountList =
        sendAccountQuery.param("targetUserId", userId).param("targetTypeUser", WebMailAccountFormData.WEBMAILACL_TARGET_TYPE_U).param(
          "targetGroupSendId",
          groupSendIdList).param("targetTypeGroupSend", WebMailAccountFormData.WEBMAILACL_TARGET_TYPE_G).param(
          "aclType",
          WebMailAccountFormData.WEBMAILACL_ACL_TYPE_S).fetchList();

      // 取得されない場合は終了
      if (accountList == null) {
        return null;
      }

      WebmailAccountLiteBean bean = null;

      // 代理送信元アカウントの部署・役職情報
      List<UserGroupPositionLiteBean> userPostPositionList = new ArrayList<UserGroupPositionLiteBean>();

      // 代理送信元アカウント情報リストの設定
      Iterator<EipMMailAccount> iter = accountList.iterator();
      while (iter.hasNext()) {
        EipMMailAccount account = iter.next();
        bean = new WebmailAccountLiteBean();
        bean.initField();
        bean.setAccountId(account.getAccountId()); // 代理送信元アカウントID
        // 代理送信元アカウントの部署・役職情報取得
        userPostPositionList = UserUtils.getPostPositionBeanList(account.getUserId());
        UserGroupPositionLiteBean userPostPosition = userPostPositionList.get(0);
        StringBuffer accountName = new StringBuffer();
        // 部署1 部署2 氏名 役職の順に設定する
        accountName
          .append(userPostPosition.getPost1Name())
          .append(" ")
          .append(userPostPosition.getPost2Name())
          .append(" ")
          .append(account.getAccountName())
          .append(" ");
        if (!(null == userPostPosition.getPositionName())) {
          accountName.append(userPostPosition.getPositionName());
        }
        bean.setAccountName(accountName.toString());
        mailAccountList.add(bean);
      }

      // add start 受入テスト障害 181
      if (isDraftAccount) {
        // 代理送信メールを下書きしている場合は、代理アカウントIDが有効なのかチェックする。
        boolean found = false;
        for (WebmailAccountLiteBean b : mailAccountList) {
          if (b.getAccountId().getValueAsString().equals(draftAccountId)) {
            found = true;
            break;
          }
        }
        if (!found) {
          // 下書き保存している間に代理送信権限が削除されてしまったパターン対応
          draftAccountId = "";
        }
      }
      // add end

      return mailAccountList;

    } catch (Exception e) {
      // logger.error("Exception", e);
      // add start
      String msg = "メール作成 代理送信アカウント取得に失敗しました。[" + ALEipUtils.getBaseUser(userId).getUserName() + "]";
      logger.error(msg, e);
      throw e;
      // add end
    }
  }

  /**
   * 宛先を引用する 取得<BR>
   * 
   * @return quoteTo
   */
  public ALStringField getQuoteTo() {
    return quoteTo;
  }

  /**
   * 宛先を引用する 設定<BR>
   * 
   * @param quoteTo
   */
  public void setQuoteTo(ALStringField quoteTo) {
    this.quoteTo = quoteTo;
  }

  /**
   * 本文を引用する 取得<BR>
   * 
   * @return quoteBody
   */
  public ALStringField getQuoteBody() {
    return quoteBody;
  }

  /**
   * 本文を引用する 設定<BR>
   * 
   * @param quoteBody
   */
  public void setQuoteBody(ALStringField quoteBody) {
    this.quoteBody = quoteBody;
  }

  /**
   * 本文に引用符を付ける 取得<BR>
   * 
   * @return addQuotationMarks
   */
  public ALStringField getAddQuotationMarks() {
    return addQuotationMarks;
  }

  /**
   * 本文に引用符を付ける 設定<BR>
   * 
   * @param addQuotationMarks
   */
  public void setAddQuotationMarks(ALStringField addQuotationMarks) {
    this.addQuotationMarks = addQuotationMarks;
  }

  /**
   * TO(参照入力宛先表示名)取得<BR>
   * 
   * @return toNames
   */
  public ALStringField getToNames() {
    return toNames;
  }

  /**
   * CC(参照入力宛先表示名)取得<BR>
   * 
   * @return ccNames
   */
  public ALStringField getCcNames() {
    return ccNames;
  }

  /**
   * BCC(参照入力宛先表示名)取得<BR>
   * 
   * @return bccNames
   */
  public ALStringField getBccNames() {
    return bccNames;
  }

  /**
   * 宛先（グループ送信）取得<BR>
   * 
   * @return toGroupsend
   */
  public ALStringField getToGroupsend() {
    return toGroupsend;
  }

  /**
   * 宛先（社内アドレス）取得<BR>
   * 
   * @return toCorp
   */
  public ALStringField getToCorp() {
    return toCorp;
  }

  /**
   * CC（社内アドレス）取得<BR>
   * 
   * @return ccCorp
   */
  public ALStringField getCcCorp() {
    return ccCorp;
  }

  /**
   * BCC（社内アドレス）取得<BR>
   * 
   * @return bccCorp
   */
  public ALStringField getBccCorp() {
    return bccCorp;
  }

  /**
   * 宛先（個人アドレス）取得<BR>
   * 
   * @return toExt
   */
  public ALStringField getToExt() {
    return toExt;
  }

  /**
   * CC（個人アドレス）取得<BR>
   * 
   * @return ccExt
   */
  public ALStringField getCcExt() {
    return ccExt;
  }

  /**
   * BCC（個人アドレス）取得<BR>
   * 
   * @return bccExt
   */
  public ALStringField getBccExt() {
    return bccExt;
  }

  /**
   * 宛先（グループ送信）設定<BR>
   * 
   * @param toGroupsend
   */
  public void setToGroupsend(ALStringField toGroupsend) {
    this.toGroupsend = toGroupsend;
  }

  /**
   * CC（グループ送信）取得<BR>
   * 
   * @return ccGroupsend
   */
  public ALStringField getCcGroupsend() {
    return ccGroupsend;
  }

  /**
   * CC（グループ送信）設定<BR>
   * 
   * @param ccGroupsend
   */
  public void setCcGroupsend(ALStringField ccGroupsend) {
    this.ccGroupsend = ccGroupsend;
  }

  /**
   * BCC（グループ送信）取得<BR>
   * 
   * @return bccGroupsend
   */
  public ALStringField getBccGroupsend() {
    return bccGroupsend;
  }

  /**
   * BCC（グループ送信）設定<BR>
   * 
   * @param bccGroupsend
   */
  public void setBccGroupsend(ALStringField bccGroupsend) {
    this.bccGroupsend = bccGroupsend;
  }

  /**
   * 送信元アカウントID 取得<BR>
   * 
   * @return fromAccountId
   */
  public ALNumberField getFromAccountId() {
    return fromAccountId;
  }

  /**
   * 送信元アカウントID 設定<BR>
   * 
   * @param fromAccountId
   */
  public void setFromAccountId(ALNumberField fromAccountId) {
    this.fromAccountId = fromAccountId;
  }

  /**
   * 代理受信フラグを返す。<BR>
   * 
   * @return isRepresent
   */
  public boolean isRepresent() {
    return isRepresent;
  }

  // add end

  // public String getCurrentGroupName() {
  // return current_group_name;
  // }
  //
  // public String getCurrentParentGroupName() {
  // return current_parent_group_name;
  // }
  //
  // public List<UserGroupLiteBean> getChildGroupList() {
  //
  // if (current_parent_group_name != null
  // && current_parent_group_name.length() > 0) {
  // return UserUtils.getPost2LiteBeans(current_parent_group_name);
  // }
  // return new ArrayList<UserGroupLiteBean>();
  // }
  // add end

  // add start by motegi 20111108
  /**
   * 開いているフォームが下書きか？
   * 
   * @return 下書き：true、それ以外:false
   */
  public boolean isDraft() {
    return getMailType().getValue() == TYPE_DRAFT_MAIL;
  }

  // 運用課題No.98(#351) 直接入力宛先をCSVParserに対応
  /**
   * 直接入力宛先をCSVParserで分割できるよう編集する。
   * 
   * @param directInputDestination
   *            直接入力宛先
   * @return CSVParserに対応した直接入力宛先
   */
  private String convertDirectInputDestination(String directInputDestination) {
    // 携帯版、NULL、空文字の場合は当処理を実行しない
    if (isCellularSmartPhone || null == directInputDestination || "".equals(directInputDestination)) {
      return directInputDestination;
    }
    String delim = ",";
    String convertDirectInputDestination = "";
    String[] destinations = ALMailUtils.getTokens(directInputDestination, delim);
    int count = 0;
    for (String destination : destinations) {
      // 2件以降は先頭に区切り文字を設定
      if (count > 0) {
        convertDirectInputDestination += delim;
      }
      // 制御文字をエスケープ
      destination = CSVParser.replaceCsvEscapeCharacter(destination);

      // 引用符付きに加工
      destination = CSVParser.putQuotechar(destination);

      // CSVデータに設定
      convertDirectInputDestination += destination;

      count++;
    }
    return convertDirectInputDestination;
  }

  // remove start 運用障害9 2012.4.25
  // public void setAddress(ALStringField target, String addresses)
  // throws AddressException {
  // // TOにグループ送信のアドレスを連結するためのフィールド
  // StringBuffer toAppendGroup = new StringBuffer();
  //
  // // 個人指定（グループ送信ではない）のTO
  // toAppendGroup.append(target.getValue());
  //
  // String tmp = connectMailAddressForNormalAddress(addresses);
  // if (!(null == toAppendGroup) && toAppendGroup.length() > 0) {
  // if (tmp.length() > 0) {
  // toAppendGroup.append(",");
  // }
  // }
  //
  // // TOのグループ送信の全アドレスを個人指定のTOに連結
  // toAppendGroup.append(tmp);
  //
  // // TOの値を入れ替え
  // target.setValue(toAppendGroup.toString());
  // }
  // remove end

  /**
   * アドレス帳選択宛先（社内、グループ送信、社外）設定
   * 
   * @param rundata
   *            実行データ
   * @param target
   *            設定先文字列フィールド
   * @param groupsends
   *            設定元宛先
   * @throws AddressException
   *             メールアドレスが設定されていない宛先を使用した場合
   */
  public void setGroupSendAddress(RunData rundata, ALStringField target, String groupsends) throws AddressException {

    // targetにグループ送信のアドレスを連結するためのフィールド
    StringBuffer toAppendGroup = new StringBuffer();
    // 個人指定（グループ送信ではない）のtarget
    toAppendGroup.append(target.getValue());
    // 個人指定のtargetがある場合は間にカンマを入れる
    // if (!(null == toAppendGroup) && toAppendGroup.length() > 0) {
    // toAppendGroup.append(",");
    // }
    // TOのグループ送信の全アドレスを個人指定のTOに連結
    // change start 運用障害9 2012.4.25
    // String tmp = connectMailAddress(rundata, groupsends);
    String tmp = connectMailAddressForNormalAddress(rundata, groupsends);
    // change end
    if (!(null == toAppendGroup) && toAppendGroup.length() > 0) {
      if (tmp.length() > 0) {
        toAppendGroup.append(",");
      }
    }
    toAppendGroup.append(tmp);

    // targetの値を入れ替え
    target.setValue(toAppendGroup.toString());
  }

  /**
   * メール作成画面で参照入力のTo, CC, BCCのためのHiddenデータを生成する。
   * 
   * @param person
   *            表示名
   * @param address
   *            メールアドレス
   * @param login_user_id
   *            ログインユーザーID
   * @return Hiddenパラメータ用のデータ
   */
  private WebmailHiddenDataBean getHiddenData(String person, String address, int login_user_id) throws ALDBErrorException {

    int id = 0;
    String name = "";
    String prefix = "";

    // 社内アドレスに合致するメールアドレスがあるか検索する。
    TurbineUser tuser = Database.query(TurbineUser.class).where(Operations.eq(TurbineUser.EMAIL_PROPERTY, address)).fetchSingle();
    if (tuser == null) {
      // 社内アドレスに無ければ、個人アドレス帳を検索する。
      EipMAddressbook ext =
        Database.query(EipMAddressbook.class).where(
          Operations.eq(EipMAddressbook.OWNER_ID_PROPERTY, login_user_id),
          Operations.eq(EipMAddressbook.EMAIL_PROPERTY, address)).fetchSingle();
      if (ext == null) {
        return null;
      }
      id = ext.getAddressId();
      // change start for 受入テスト障害320
      // name = person;
      name = ext.getLastName();
      if (ext.getFirstName() != null && !"".equals(ext.getFirstName())) {
        name = name + " " + ext.getFirstName();
      }
      // change end
      prefix = PREFIX_EXT_ADDRESS;
    } else {
      id = tuser.getUserId();
      name = tuser.getLastName() + " " + tuser.getFirstName();
      prefix = PREFIX_COPR_ADDRESS;
    }

    // hidden用データ
    String result = prefix + " " + id + " " + name + "<" + address + ">";

    WebmailHiddenDataBean bean = new WebmailHiddenDataBean();
    bean.setDisplayData(name);
    bean.setPrefix(prefix);
    bean.setHiddenData(result);

    return bean;
  }

  /**
   * メールアドレスリストを社内アドレス、個人アドレス帳のアドレスと比較して、参照入力欄に表示できるように加工する。
   * 
   * @param tos
   *            アドレスリスト
   * @param names
   *            参照入力表示欄用データ
   * @param corp
   *            参照入力hidden用データ（社内アドレス）
   * @param ext
   *            参照入力hidden用データ（個人アドレス）
   * @return 変換できなかった（Aipoに情報の無い）アドレス情報 直接入力欄に表示する
   * @throws ALDBErrorException
   */
  // change start 2012.04.25
  // private Address[] convertMailAddress2Name(Address[] tos, ALStringField
  // names,
  // ALStringField corp, ALStringField ext) throws ALDBErrorException {
  private Address[] convertMailAddress2Name(Address[] tos, ALStringField names, ALStringField hiddenValue) throws ALDBErrorException {
    // change end 2012.04.25
    if (tos == null) {
      return null;
    }

    StringBuffer tmpToNames = new StringBuffer();
    // change start 運用障害9 2012.4.25
    // StringBuffer tmpToCorp = new StringBuffer();
    // StringBuffer tmpToExt = new StringBuffer();
    StringBuffer tmpHiddenValue = new StringBuffer();
    // change end

    int size = tos.length;
    List<Address> tmpTos = new ArrayList<Address>();
    for (int i = 0; i < size; i++) {

      InternetAddress addr = (InternetAddress) tos[i];

      WebmailHiddenDataBean tmp = getHiddenData(addr.getPersonal(), addr.getAddress(), userId);

      if (tmp == null) {
        tmpTos.add(addr);
        continue;
      }

      // change start 運用障害9 2012.4.25
      // if (PREFIX_COPR_ADDRESS.equals(tmp.getPrefix())) {
      // if (tmpToCorp.length() == 0) {
      // tmpToCorp.append(tmp.getHiddenData());
      // } else {
      // // tmpToCorp.append("," + tmp.getHiddenData());
      // tmpToCorp.append("\n" + tmp.getHiddenData());
      // }
      // } else {
      // if (tmpToExt.length() == 0) {
      // tmpToExt.append(tmp.getHiddenData());
      // } else {
      // // tmpToExt.append("," + tmp.getHiddenData());
      // tmpToExt.append("\n" + tmp.getHiddenData());
      // }
      // }
      if (PREFIX_COPR_ADDRESS.equals(tmp.getPrefix())) {
        if (tmpHiddenValue.length() == 0) {
          tmpHiddenValue.append(tmp.getHiddenData());
        } else {
          // tmpToCorp.append("," + tmp.getHiddenData());
          tmpHiddenValue.append("\n" + tmp.getHiddenData());
        }
      } else {
        if (tmpHiddenValue.length() == 0) {
          tmpHiddenValue.append(tmp.getHiddenData());
        } else {
          // tmpToExt.append("," + tmp.getHiddenData());
          tmpHiddenValue.append("\n" + tmp.getHiddenData());
        }
      }
      // change end

      if (tmpToNames.length() == 0) {
        tmpToNames.append(tmp.getDisplayData());
      } else {
        tmpToNames.append("," + tmp.getDisplayData());
      }
    }
    names.setValue(tmpToNames.toString());
    // corp.setValue(tmpToCorp.toString());
    // ext.setValue(tmpToExt.toString());
    hiddenValue.setValue(tmpHiddenValue.toString());

    tos = tmpTos.toArray(new Address[tmpTos.size()]);

    return tos;
  }

  /**
   * 現在選択されているタブを取得します。 受入テスト障害168<BR>
   * 
   * @return
   */
  public String getCurrentTab() {
    return currentTab;
  }

  public boolean isCellularSmartPhone() {
    return isCellularSmartPhone;
  }

  public void setCellularSmartPhone(boolean isCellularSmartPhone) {
    this.isCellularSmartPhone = isCellularSmartPhone;
  }

  // 携帯用
  /**
   * To（グループ送信）表示名を返す。
   * 
   * @return BCC（グループ送信）表示名
   */
  public String getToGroupsendName() {
    return toGroupsendName;
  }

  /**
   * CC（グループ送信）表示名を返す。
   * 
   * @return BCC（グループ送信）表示名
   */
  public String getCcGroupsendName() {
    return ccGroupsendName;
  }

  /**
   * BCC（グループ送信）表示名を返す。
   * 
   * @return BCC（グループ送信）表示名
   */
  public String getBccGroupsendName() {
    return bccGroupsendName;
  }

  // add end

  // add start 2011/12/8
  /**
   * 下書きFrom代理送信フラグを返す。
   * 
   * @return From 代理送信：true
   */
  public boolean getIsDraftAccount() {
    return isDraftAccount;
  }

  /**
   * 下書きFrom代理送信AccountIdを返す。
   * 
   * @return From 代理送信アカウントID
   */
  public String getDraftAccountId() {
    return draftAccountId;
  }

  /**
   * 下書きFrom代理送信AccountIdをセットする。
   * 
   * @parum 代理送信アカウントID
   */
  public void setDraftAccountId(String draftAccountId) {
    this.draftAccountId = draftAccountId;
  }

  /**
   * InputStreamをバイト配列に変換する
   * 
   * @param is
   * @return バイト配列
   */
  private static byte[] getBytes(InputStream is) {
    // byte型の配列を出力する
    ByteArrayOutputStream b = new ByteArrayOutputStream();
    OutputStream os = new BufferedOutputStream(b);
    int c;
    try {
      while ((c = is.read()) != -1) {
        os.write(c);
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (os != null) {
        try {
          os.flush();
          os.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    return b.toByteArray();
  }

  // add end

  // add start 2011.1214 受入テスト障害109
  private static boolean noMailRecord(String orgId, String tab) {
    try {
      if (WebMailUtils.TAB_RECEIVE.equals(tab)) {
        // 受信トレイの場合
        ALMailUtils.getEipTMail(orgId);
      } else {
        // 送信トレイの場合
        ALMailUtils.getAvzTMailSend(orgId);
      }
    } catch (Exception e) {
      return true;
    }
    return false;
  }

  // add end

  // add start 2012.2.3
  // 中国語対応による下書き時のタイプを取得する
  public boolean getIsCharcodeChinese() {
    return isCharcodeChinese;
  }

  // add end

  // add start 2012.5.22
  private boolean isWrongAddressesFormat(String address) {
    InternetAddress[] persons = null;
    try {
      persons = MailUtility.parseAddresses(address);
    } catch (Exception e) {
      logger.error("InternetAddressクラスでparseできない形式のメールアドレスです。メールアドレスは「" + address + "」です。");
      return true;
    }
    return false;
  }
  // add end 2012.5.22
}
