/*
 * 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.account;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.access.Transaction;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.jetspeed.services.JetspeedSecurity;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.resources.JetspeedResources;
import org.apache.turbine.services.TurbineServices;
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.account.util.AccountUtils;
import com.aimluck.eip.cayenne.om.account.AvzMGroupsend;
import com.aimluck.eip.cayenne.om.account.AvzMRole;
import com.aimluck.eip.cayenne.om.account.AvzMUserGroupsend;
import com.aimluck.eip.cayenne.om.account.AvzMUserRole;
import com.aimluck.eip.cayenne.om.account.EipMUserPosition;
import com.aimluck.eip.cayenne.om.security.TurbineUser;
import com.aimluck.eip.common.ALAbstractFormData;
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.ALEipManager;
import com.aimluck.eip.common.ALEipPosition;
import com.aimluck.eip.common.ALEipPost;
import com.aimluck.eip.common.ALEipRole;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.fileupload.beans.FileuploadLiteBean;
import com.aimluck.eip.fileupload.util.FileuploadUtils;
import com.aimluck.eip.modules.actions.common.ALAction;
import com.aimluck.eip.orm.Database;
import com.aimluck.eip.orm.query.SelectQuery;
import com.aimluck.eip.services.accessctl.ALAccessControlFactoryService;
import com.aimluck.eip.services.accessctl.ALAccessControlHandler;
import com.aimluck.eip.services.config.ALConfigService;
import com.aimluck.eip.services.config.ALConfigHandler.Property;
import com.aimluck.eip.services.datasync.ALDataSyncFactoryService;
import com.aimluck.eip.services.storage.ALStorageService;
import com.aimluck.eip.user.beans.UserGroupLiteBean;
import com.aimluck.eip.user.beans.UserGroupPositionLiteBean;
import com.aimluck.eip.user.util.UserUtils;
import com.aimluck.eip.util.ALEipUtils;

/**
 * ユーザーアカウントのフォームデータを管理するクラスです。 <BR>
 * 
 */
public class AccountUserFormData extends ALAbstractFormData {

  /** logger */
  private static final JetspeedLogger logger =
    JetspeedLogFactoryService.getLogger(AccountUserFormData.class.getName());

  /** ブラウザに表示するデフォルトのパスワード（ダミーパスワード） */
  private static final String DEFAULT_VIEW_PASSWORD = "******";

  /** ユーザー名 */
  private ALStringField username;

  /** パスワード */
  private ALStringField password;

  /** パスワード */
  private ALStringField password2;

  /** 名前（名） */
  private ALStringField firstname;

  /** 名前（姓） */
  private ALStringField lastname;

  /** メールアドレス */
  private ALStringField email;

  /** アカウント有効/無効 */
  private ALStringField disabled;

  /** 電話番号（内線） */
  private ALStringField in_telephone;

  /** 電話番号 */
  private ALStringField out_telephone1;

  /** 電話番号 */
  private ALStringField out_telephone2;

  /** 電話番号 */
  private ALStringField out_telephone3;

  /** 電話番号（携帯） */
  private ALStringField cellular_phone1;

  /** 電話番号（携帯） */
  private ALStringField cellular_phone2;

  /** 電話番号（携帯） */
  private ALStringField cellular_phone3;

  /** 携帯メールアドレス */
  private ALStringField cellular_mail;

  /** 会社 ID */
  private ALNumberField company_id;

  /** 役職 ID */
  private ALNumberField position_id;

  /** 部署 ID */
  private ALNumberField post_id;

  /** フリガナ（名） */
  private ALStringField first_name_kana;

  /** フリガナ（姓） */
  private ALStringField last_name_kana;

  /** 顔写真 */
  private ALStringField photo = null;

  /** 添付ファイル */
  private FileuploadLiteBean filebean = null;

  /** 添付フォルダ名 */
  private String folderName = null;

  /** 部署リスト */
  private List<UserGroupLiteBean> postList;

  /** 役職リスト */
  private List<ALEipPosition> positionList;

  /** 部署 */
  private AccountPostFormData post;

  /** 役職 */
  private AccountPositionFormData position;

  /** 管理者権限を付与するか */
  private ALStringField is_admin;

  /** */
  private boolean is_new_post;

  /** */
  private boolean is_new_position;

  /** パスワード変更の可否．変更する場合は，false． */
  private boolean dontUpdatePasswd = false;

  private String orgId;

  /** 顔写真データ */
  private byte[] facePhoto;

  /** ログインしている人のユーザーID */
  private int login_uid;

  private boolean isSkipUsernameValidation = false;

  // add by motegi start グループ送信対応
  /** 職種名 */
  private ALStringField category_name;

  // add by motegi start 端末認証対応
  /** 携帯端末固有番号 */
  private ALStringField cellular_uid;

  /** 表示名 */
  private ALStringField display_name;

  /** 役割リスト */
  private List<ALEipRole> role_list;

  /** グループ送信リスト */
  private List<ALEipGroupSend> groupsend_list;

  // add by motegi start 複数部署・役職対応
  /** 部署・役職リスト */
  private List<UserGroupPositionLiteBean> post_position_list;

  /**
   * 初期処理
   * 
   * @param action
   *          アクションクラス
   * @param rundata
   *          JetSpeedランデータ
   * @param context
   *          JetSpeedコンテキスト
   * @see com.aimluck.eip.common.ALAbstractFormData#init(com.aimluck.eip.modules.actions.common.ALAction,
   *      org.apache.turbine.util.RunData, org.apache.velocity.context.Context)
   */
  @Override
  public void init(ALAction action, RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {
    super.init(action, rundata, context);

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

    is_new_post = rundata.getParameters().getBoolean("is_new_post");
    is_new_position = rundata.getParameters().getBoolean("is_new_position");

    orgId = Database.getDomainName();

    login_uid = ALEipUtils.getUserId(rundata);
  }

  /**
   * 各フィールドを初期化します。 <BR>
   * 
   * 
   */
  @Override
  public void initField() {
    // ログイン名
    username = new ALStringField();
    username.setFieldName("ログイン名");
    username.setTrim(true);
    // パスワード
    password = new ALStringField();
    password.setFieldName("パスワード");
    password.setTrim(true);
    // パスワード2
    password2 = new ALStringField();
    password2.setFieldName("パスワード（確認用）");
    password2.setTrim(true);
    // 名
    firstname = new ALStringField();
    firstname.setFieldName("名前（名）");
    firstname.setTrim(true);
    // 姓
    lastname = new ALStringField();
    lastname.setFieldName("名前（姓）");
    lastname.setTrim(true);
    // メールアドレス
    email = new ALStringField();
    email.setFieldName("メールアドレス");
    email.setTrim(true);
    // アカウント有効/無効
    disabled = new ALStringField();
    disabled.setFieldName("アカウント有効/無効");
    disabled.setTrim(true);
    // 内線番号
    in_telephone = new ALStringField();
    in_telephone.setFieldName("電話番号（内線）");
    in_telephone.setTrim(true);

    // 外線番号
    out_telephone1 = new ALStringField();
    out_telephone1.setFieldName("電話番号（外線）");
    out_telephone1.setTrim(true);
    out_telephone2 = new ALStringField();
    out_telephone2.setFieldName("電話番号（外線）");
    out_telephone2.setTrim(true);
    out_telephone3 = new ALStringField();
    out_telephone3.setFieldName("電話番号（外線）");
    out_telephone3.setTrim(true);

    // 携帯番号
    cellular_phone1 = new ALStringField();
    cellular_phone1.setFieldName("電話番号（携帯）");
    cellular_phone1.setTrim(true);
    cellular_phone2 = new ALStringField();
    cellular_phone2.setFieldName("電話番号（携帯）");
    cellular_phone2.setTrim(true);
    cellular_phone3 = new ALStringField();
    cellular_phone3.setFieldName("電話番号（携帯）");
    cellular_phone3.setTrim(true);

    // 携帯アドレス
    cellular_mail = new ALStringField();
    cellular_mail.setFieldName("携帯メールアドレス");
    cellular_mail.setTrim(true);
    // 名（フリガナ）
    first_name_kana = new ALStringField();
    first_name_kana.setFieldName("名前（フリガナ）");
    first_name_kana.setTrim(true);
    // 姓（フリガナ）
    last_name_kana = new ALStringField();
    last_name_kana.setFieldName("名前（フリガナ）");
    last_name_kana.setTrim(true);
    // 顔写真
    photo = new ALStringField();
    photo.setFieldName("顔写真");
    photo.setTrim(true);

    // 部署ID
    post_id = new ALNumberField();
    post_id.setFieldName("部署");

    // 役職ID
    position_id = new ALNumberField();
    position_id.setFieldName("役職");

    // 管理者権限を付与するか
    is_admin = new ALStringField();
    is_admin.setFieldName("管理者にする");
    is_admin.setTrim(true);

    post = new AccountPostFormData();
    post.setJoinMember(false);
    post.initField();

    position = new AccountPositionFormData();
    position.initField();

    // add by motegi start グループ送信対応
    category_name = new ALStringField();
    category_name.setFieldName("職種");
    category_name.setTrim(true);
    // add by motegi start 端末認証対応
    cellular_uid = new ALStringField();
    cellular_uid.setFieldName("携帯端末固有番号");
    cellular_uid.setTrim(true);
    // add by motegi start 表示名
    display_name = new ALStringField();
    display_name.setFieldName("表示名");
    display_name.setTrim(true);

  }

  /**
   * フォームデータ処理
   * 
   * @param rundata
   *          JetSpeedランデータ
   * @param context
   *          JetSpeedコンテキスト
   * @param msgList
   *          エラーメッセージリスト
   * @return 処理結果(正常：true、異常:false)
   * @see com.aimluck.eip.common.ALAbstractFormData#loadFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  @Override
  protected boolean setFormData(RunData rundata, Context context,
      List<String> msgList) throws ALPageNotFoundException, ALDBErrorException {
    boolean res = super.setFormData(rundata, context, msgList);
    try {
      if (res) {
        post.setFormData(rundata, context, msgList);
        position.setFormData(rundata, context, msgList);

        List<FileuploadLiteBean> fileBeanList =
          FileuploadUtils.getFileuploadList(rundata);
        if (fileBeanList != null && fileBeanList.size() > 0) {
          filebean = fileBeanList.get(0);
          if (filebean.getFileId() > 0) {
            // 顔写真をセットする．
            String[] acceptExts = ImageIO.getWriterFormatNames();
            facePhoto =
              FileuploadUtils.getBytesShrinkFilebean(
                orgId,
                folderName,
                ALEipUtils.getUserId(rundata),
                filebean,
                acceptExts,
                FileuploadUtils.DEF_THUMBNAIL_WIDTH,
                FileuploadUtils.DEF_THUMBNAIL_HEIGTH,
                msgList);
          } else {
            facePhoto = null;
          }
        }
      }
    } catch (Exception ex) {
      logger.error("Exception", ex);
      res = false;
    }
    return res;
  }

  /**
   * バリデータ初期化
   * 
   * @see com.aimluck.eip.common.ALAbstractFormData#setValidator()
   */
  @Override
  protected void setValidator() {
    // ユーザー名
    username.setNotNull(true);
    username.setCharacterType(ALStringField.TYPE_ASCII);
    username.limitMaxLength(16);
    // パスワード
    password.setNotNull(true);
    password.setCharacterType(ALStringField.TYPE_ALPHABET_NUMBER);
    password.limitMaxLength(16);
    // パスワード2
    password2.setNotNull(true);
    password2.setCharacterType(ALStringField.TYPE_ALPHABET_NUMBER);
    password2.limitMaxLength(16);
    // 名
    firstname.setNotNull(true);
    firstname.limitMaxLength(20);
    // 姓
    lastname.setNotNull(true);
    lastname.limitMaxLength(20);

    // 名（フリガナ）
    first_name_kana.setNotNull(true);
    first_name_kana.limitMaxLength(20);
    // 姓（フリガナ）
    last_name_kana.setNotNull(true);
    last_name_kana.limitMaxLength(20);

    // 内線
    // in_telephone.setCharacterType(ALStringField.TYPE_ALPHABET_NUMBER);
    in_telephone.setCharacterType(ALStringField.TYPE_ASCII);
    in_telephone.limitMaxLength(13);
    // メールアドレス
    email.setCharacterType(ALStringField.TYPE_ASCII);
    // change start 2012.1.23
    // email.limitMaxLength(50);
    email.limitMaxLength(64);
    // change end

    // 外線
    out_telephone1.setCharacterType(ALStringField.TYPE_NUMBER);
    out_telephone1.limitMaxLength(5);
    out_telephone2.setCharacterType(ALStringField.TYPE_NUMBER);
    out_telephone2.limitMaxLength(4);
    out_telephone3.setCharacterType(ALStringField.TYPE_NUMBER);
    out_telephone3.limitMaxLength(4);

    // 携帯
    cellular_phone1.setCharacterType(ALStringField.TYPE_NUMBER);
    cellular_phone1.limitMaxLength(5);
    cellular_phone2.setCharacterType(ALStringField.TYPE_NUMBER);
    cellular_phone2.limitMaxLength(4);
    cellular_phone3.setCharacterType(ALStringField.TYPE_NUMBER);
    cellular_phone3.limitMaxLength(4);
    // 携帯メール
    cellular_mail.setCharacterType(ALStringField.TYPE_ASCII);
    cellular_mail.limitMaxLength(64);
    // remove start
    // post.setValidator();
    // position.setValidator();
    // remove end

    // add start
    // 表示名
    display_name.setNotNull(true);
    display_name.limitMaxLength(50);

    // 職種
    category_name.limitMaxLength(50);

    // 端末固有番号
    cellular_uid.setCharacterType(ALStringField.TYPE_ASCII);
    cellular_uid.limitMaxLength(50);
  }

  /**
   * フォームに入力されたデータの妥当性検証を行います。 <BR>
   * 
   * @param msgList
   * @return
   * 
   */
  @Override
  protected boolean validate(List<String> msgList) {
    ArrayList<String> dummy = new ArrayList<String>();
    if (!isSkipUsernameValidation) {
      username.validate(msgList);
      if (ALEipConstants.MODE_INSERT.equals(getMode())) {
        try {
          Expression exp =
            ExpressionFactory.matchExp(
              TurbineUser.LOGIN_NAME_PROPERTY,
              username.getValue());
          SelectQuery<TurbineUser> query =
            Database.query(TurbineUser.class, exp);
          List<TurbineUser> ulist = query.fetchList();
          if (ulist.size() > 0) {
            msgList.add("ログイン名『 <span class='em'>"
              + username
              + "</span> 』はすでに登録されています。別のログイン名で登録してください。");
          }
        } catch (Exception ex) {
          // change start
          // logger.error("Exception", ex);
          String mode = "登録";
          if (ALEipConstants.MODE_UPDATE.equals(getMode())) {
            mode = "更新";
          }
          String msg = "ユーザー情報の" + mode + "に失敗しました。";
          logger.error(msg, ex);
          msgList.add(msg);
          // change end
          return false;
        }
      }

      if (!AccountUtils.isValidSymbolUserName(username.getValue())) {
        StringBuffer msg =
          new StringBuffer("『 <span class='em'>ログイン名</span> 』に使用できる記号は");
        List<String> symbols = Arrays.asList(AccountUtils.USER_NAME_SYMBOLS);
        for (String symbol : symbols) {
          msg.append("『").append(symbol).append("』");
        }
        msg.append("のみです。");
        msgList.add(msg.toString());
      }

      // ユーザー名の先頭にdummy_が含まれるかの確認
      if (ALEipConstants.MODE_INSERT.equals(getMode())) {
        if (username.getValue().length() > 5) {
          if (ALEipUtils.dummy_user_head.equals((username.getValue())
            .substring(0, 6))) {
            msgList.add("ログイン名の先頭に『 <span class='em'>"
              + ALEipUtils.dummy_user_head
              + "</span> 』は使用出来ません。別のログイン名で登録してください。");
          }
        }
      }
    }

    // パスワードの確認
    if (ALEipConstants.MODE_INSERT.equals(getMode())) {
      if (!password.getValue().equals(password2.getValue())) {
        msgList
          .add("『 <span class='em'>パスワード</span> 』と『 <span class='em'>パスワード（確認用）</span> 』を正しく入力してください。");
      } else {
        password.validate(msgList);
        password2.validate(msgList);
      }
    } else if (ALEipConstants.MODE_UPDATE.equals(getMode())) {
      if (password.getValue().equals(DEFAULT_VIEW_PASSWORD)
        && password2.getValue().equals(DEFAULT_VIEW_PASSWORD)) {
        dontUpdatePasswd = true;
      } else {
        if (!password.getValue().equals(password2.getValue())) {
          msgList
            .add("『 <span class='em'>パスワード</span> 』と『 <span class='em'>パスワード（確認用）</span> 』を正しく入力してください。");
        } else {
          password.validate(msgList);
          password2.validate(msgList);
        }
      }
    }

    firstname.validate(msgList);
    lastname.validate(msgList);

    // フリガナのカタカナへの変換
    first_name_kana.setValue(ALStringUtil.convertHiragana2Katakana(ALStringUtil
      .convertH2ZKana(first_name_kana.getValue())));
    last_name_kana.setValue(ALStringUtil.convertHiragana2Katakana(ALStringUtil
      .convertH2ZKana(last_name_kana.getValue())));
    first_name_kana.validate(msgList);
    last_name_kana.validate(msgList);

    // メールアドレス
    email.validate(msgList);
    if (email.getValue() != null
      && email.getValue().trim().length() > 0
      && !ALStringUtil.isMailAddress(email.getValue())) {
      msgList.add("『 <span class='em'> メールアドレス </span>』を正しく入力してください。");
    }

    if (!out_telephone1.getValue().equals("")
      || !out_telephone2.getValue().equals("")
      || !out_telephone3.getValue().equals("")) {

      if (!out_telephone1.validate(dummy)
        || !out_telephone2.validate(dummy)
        || !out_telephone3.validate(dummy)) {
        msgList.add("『 <span class='em'>電話番号（外線）</span> 』を正しく入力してください。");
      } else {
        // 電話番号の長さチェック
        int req_size =
          out_telephone1.getValue().length()
            + out_telephone2.getValue().length()
            + out_telephone3.getValue().length();
        int limit_size =
          out_telephone1.getMaxLength()
            + out_telephone2.getMaxLength()
            + out_telephone3.getMaxLength();
        if (req_size > limit_size) {
          msgList.add("『 <span class='em'>電話番号（外線）</span> 』を"
            + limit_size
            + "桁以内で正しく入力してください。");
        }
      }
    }

    in_telephone.validate(msgList);
    // ハイフン以外の記号とアルファベットの入力をはじきます
    Pattern pattern = Pattern.compile(".*[^-0-9]+.*");
    Matcher matcher = pattern.matcher(in_telephone.getValue());
    Boolean ext_validater = matcher.matches();
    if (ext_validater) {
      msgList.add("電話番号（内線）は 13 文字以下でハイフン（-）または半角数字で入力してください。");
    }

    if (!cellular_phone1.getValue().equals("")
      || !cellular_phone2.getValue().equals("")
      || !cellular_phone3.getValue().equals("")) {
      if (!cellular_phone1.validate(dummy)
        || !cellular_phone2.validate(dummy)
        || !cellular_phone3.validate(dummy)) {
        msgList.add("『 <span class='em'>電話番号（携帯）</span> 』を正しく入力してください。");
      }
    }

    // 携帯メールアドレス
    cellular_mail.validate(msgList);
    if (cellular_mail.getValue().trim().length() > 0
      && !ALStringUtil.isCellPhoneMailAddress(cellular_mail.getValue())) {
      msgList.add("『 <span class='em'> 携帯メールアドレス </span>』を正しく入力してください。");
    }

    // 顔写真
    if (filebean != null && filebean.getFileId() > 0 && facePhoto == null) {
      msgList.add("『 <span class='em'>顔写真</span> 』にはJpeg画像を指定してください。");
    }

    if (is_new_post) {
      post.setMode(ALEipConstants.MODE_INSERT);
      post.validate(msgList);
    }
    if (is_new_position) {
      position.setMode(ALEipConstants.MODE_INSERT);
      position.validate(msgList);
    }

    // 管理者権限
    try {
      TurbineUser tuser = ALEipUtils.getTurbineUser(username.getValue());
      if (tuser != null
        && ALEipUtils.isEnabledUser(tuser.getUserId())
        && is_admin.getValue().equals("false")) {
        if (login_uid == tuser.getUserId()) {
          msgList
            .add("ログインしているユーザーの『 <span class='em'>管理者権限</span> 』を無くすことは出来ません。");
        }
        boolean wasAdmin = ALEipUtils.isAdmin(tuser.getUserId());
        if (wasAdmin) {
          // 更新で、有効なユーザーの管理者権限を無くす場合
          if (!AccountUtils.isAdminDeletable()) {
            msgList
              .add("このユーザーの『 <span class='em'>管理者権限</span> 』を削除できません。最低でも "
                + Integer.valueOf(ALConfigService
                  .get(Property.MINIMUM_ADMINISTRATOR_USER_COUNT))
                + " 人の管理者権限を持ったユーザーが必要です。");
          }
        }
      }

      // add start
      // 表示名
      display_name.validate(msgList);

      // 職種
      category_name.validate(msgList);

      // 端末固有番号
      cellular_uid.validate(msgList);
      // add end
    } catch (Exception e) {
      // change start
      // logger.error("Exception", e);
      String mode = "登録";
      if (ALEipConstants.MODE_UPDATE.equals(getMode())) {
        mode = "更新";
      }
      String msg = "ユーザー情報の" + mode + "に失敗しました。";
      logger.error(msg, e);
      msgList.add(msg);
      // change end
      return false;
    }

    return (msgList.size() == 0);
  }

  /**
   * ユーザー情報編集画面表示処理
   * 
   * @param rundata
   *          JetSpeedランデータ
   * @param context
   *          JetSpeedコンテキスト
   * @param msgList
   *          エラーメッセージリスト
   * @return 処理結果(正常：true、異常:false)
   * @see com.aimluck.eip.common.ALAbstractFormData#loadFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  @Override
  protected boolean loadFormData(RunData rundata, Context context,
      List<String> msgList) throws ALDBErrorException {
    try {
      ALBaseUser user = AccountUtils.getBaseUser(rundata, context);
      if (user == null) {
        // change start
        // return false;
        throw new Exception("指定されたユーザー情報がデータベースにありません。ユーザーID="
          + ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID));
        // change end
      }
      // ユーザー名
      username.setValue(user.getUserName());
      // パスワード
      password.setValue(DEFAULT_VIEW_PASSWORD);
      // パスワード2
      password2.setValue(DEFAULT_VIEW_PASSWORD);
      // 名前（名）
      firstname.setValue(user.getFirstName());
      // 名前（姓）
      lastname.setValue(user.getLastName());
      // メールアドレス
      email.setValue(user.getEmail());
      // 電話番号（内線）
      in_telephone.setValue(user.getInTelephone());
      // 電話番号（外線）
      StringTokenizer token;
      if (user.getOutTelephone() != null) {
        token = new StringTokenizer(user.getOutTelephone(), "-");
        if (token.countTokens() == 3) {
          out_telephone1.setValue(token.nextToken());
          out_telephone2.setValue(token.nextToken());
          out_telephone3.setValue(token.nextToken());
        }
      } // 電話番号（携帯）
      if (user.getCellularPhone() != null) {
        token = new StringTokenizer(user.getCellularPhone(), "-");
        if (token.countTokens() == 3) {
          cellular_phone1.setValue(token.nextToken());
          cellular_phone2.setValue(token.nextToken());
          cellular_phone3.setValue(token.nextToken());
        }
      } // 携帯メールアドレス
      cellular_mail.setValue(user.getCellularMail());
      // 会社ID
      // company_id.setValue(user.getCompanyId());
      // 役職ID
      position_id.setValue(user.getPositionId());
      // フリガナ（名）
      first_name_kana.setValue(user.getFirstNameKana());
      // フリガナ（姓）
      last_name_kana.setValue(user.getLastNameKana());

      // 管理者権限
      if (ALEipUtils.isAdmin(Integer.valueOf(user.getUserId()))) {
        is_admin.setValue("true");
      } else {
        is_admin.setValue("false");
      }

      if (user.getPhoto() != null) {
        filebean = new FileuploadLiteBean();
        filebean.initField();
        filebean.setFolderName("");
        filebean.setFileId(0);
        filebean.setFileName("以前の写真ファイル");
      }

      postList =
        AccountUtils.getPostBeanList(Integer.parseInt(user.getUserId()));

      // add by motegi start 複数部署・役職対応
      // 部署・役職リスト取得
      post_position_list =
        UserUtils.getPostPositionBeanList(Integer.parseInt(user.getUserId()));

      // 役割リスト取得
      role_list = UserUtils.getRoleBeanList(Integer.parseInt(user.getUserId()));

      // グループ送信リスト取得
      groupsend_list =
        UserUtils.getGroupSendBeanList(Integer.parseInt(user.getUserId()));

      // add by motegi start グループ送信対応
      /** 職種名 */
      category_name.setValue(user.getCategory());

      // add by motegi start 端末認証対応
      /** 携帯端末固有番号 */
      cellular_uid.setValue(user.getCelluarUId());

      /** 表示名 */
      display_name.setValue(user.getDisplayName());

      return true;
    } catch (Exception e) {
      String msg = "ユーザー情報の編集画面の表示に失敗しました。";
      logger.error(msg, e);
      throw new ALDBErrorException();
    }
  }

  /**
   * ユーザー登録
   * 
   * @param rundata
   *          JetSpeedランデータ
   * @param context
   *          JetSpeedコンテキスト
   * @param msgList
   *          エラーメッセージリスト
   * @return 処理結果(正常：true、異常:false)
   * @see com.aimluck.eip.common.ALAbstractFormData#loadFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  @Override
  protected boolean insertFormData(RunData rundata, Context context,
      List<String> msgList) {

    boolean res = true;
    try {

      int user_num = ALEipUtils.getCurrentUserNum(rundata);
      int max_user = ALEipUtils.getLimitUsers();
      if ((max_user > 0) && (user_num + 1 > max_user)) {
        msgList.add("ユーザー数が利用制限を超えています。");
        return false;
      }

      // WebAPIのDBへ接続できるか確認
      if (!ALDataSyncFactoryService
        .getInstance()
        .getDataSyncHandler()
        .checkConnect()) {
        msgList.add("コントロールパネルWebAPIのデータベースの接続に失敗したため、処理は実行されませんでした。");
        return false;
      }

      // if (is_new_post) {
      // // 部署登録も同時に行う場合
      // res = post.insertFormData(rundata, context, msgList);
      // if (res)
      // post_id.setValue(post.getPostId());
      // }
      // del by motegi 部署・役職複数対応
      // if (is_new_position && res) {
      // // 役職登録も同時に行う場合
      // res = position.insertFormData(rundata, context, msgList);
      // if (res) {
      // position_id.setValue(position.getPositionId());
      // }
      // }
      // del end

      if (res) { // オブジェクトモデルを生成
        ALBaseUser user = (ALBaseUser) JetspeedSecurity.getUserInstance();
        rundata.getParameters().setProperties(user);
        // ユーザー名
        user.setUserName(JetspeedSecurity.convertUserName(username.getValue()));
        Date now = new Date();
        // 作成日
        // 以下のメソッドは動作しないため、ALBaseUserにてオーバーライド
        // user.setCreateDate(now);
        user.setCreated(now);
        user.setModified(now);
        user.setLastLogin(now);
        user.setCreatedUserId(ALEipUtils.getUserId(rundata));
        user.setUpdatedUserId(ALEipUtils.getUserId(rundata));
        user.setConfirmed(JetspeedResources.CONFIRM_VALUE);
        // user.setDisabled(disabled.getValue());
        user.setDisabled("F");
        user.setPassword(password.getValue());
        user.setPasswordChanged(new Date());
        user.setInTelephone(in_telephone.getValue());
        if (!out_telephone1.getValue().equals("")
          && !out_telephone2.getValue().equals("")
          && !out_telephone3.getValue().equals("")) {
          user.setOutTelephone(new StringBuffer().append(
            out_telephone1.getValue()).append("-").append(
            out_telephone2.getValue()).append("-").append(
            out_telephone3.getValue()).toString());
        } else {
          user.setOutTelephone("");
        }

        if (!cellular_phone1.getValue().equals("")
          && !cellular_phone2.getValue().equals("")
          && !cellular_phone3.getValue().equals("")) {
          user.setCellularPhone(new StringBuffer().append(
            cellular_phone1.getValue()).append("-").append(
            cellular_phone2.getValue()).append("-").append(
            cellular_phone3.getValue()).toString());
        } else {
          user.setCellularPhone("");
        }
        user.setCellularMail(cellular_mail.getValue());
        user.setCompanyId(1);
        user.setPositionId((int) position_id.getValue());
        user.setPostId((int) post_id.getValue());
        user.setFirstNameKana(first_name_kana.getValue());
        user.setLastNameKana(last_name_kana.getValue());

        // add by motegi start
        user.setCelluarUId(cellular_uid.getValue());
        user.setCategory(category_name.getValue());
        user.setDisplayName(display_name.getValue());
        // add end

        if (is_admin.getValue() != null) {
          // is_adminの値が渡されなかった場合はデフォルトとして処理。
          if (is_admin.getValue().equals("true")) {
            user.setPerm("isAdmin", true);
          } else {
            user.setPerm("isAdmin", false);
          }
        }
        if (filebean != null && filebean.getFileId() > 0) {
          // 顔写真を登録する．
          user.setPhoto(facePhoto);
        }

        // ユーザーを追加
        JetspeedSecurity.addUser(user);
        logger.debug("JOIN GROUP:" + "LoginUser");

        // change by motegi start 複数部署・役職対応
        // ユーザーをグループに追加。
        // String[] groups = rundata.getParameters().getStrings("group_to");
        // if (groups != null && groups.length != 0) {
        // for (int i = 0; i < groups.length; i++) {
        // JetspeedSecurity.joinGroup(user.getUserName(), groups[i]);
        // }
        // }
        String[] post2_ids = rundata.getParameters().getStrings("post2_id[]");
        String[] position_ids =
          rundata.getParameters().getStrings("position_id[]");
        final String defaultRole = "user";
        if (post2_ids != null && post2_ids.length != 0) {
          for (int i = 0; i < post2_ids.length; i++) {
            JetspeedSecurity.joinGroup(
              user.getUserName(),
              post2_ids[i],
              defaultRole,
              position_ids[i]);
          }
        }

        // 役割情報登録
        String[] role_ids = rundata.getParameters().getStrings("role_to");
        if (role_ids != null && role_ids.length != 0) {
          for (int i = 0; i < role_ids.length; i++) {
            AvzMRole role = Database.get(AvzMRole.class, role_ids[i]);
            AvzMUserRole user_role = Database.create(AvzMUserRole.class);
            user_role.setToAvzMRole(role);
            user_role.setUserId(Integer.valueOf(user.getUserId()));
          }
        }

        // グループ送信情報登録
        String[] groupsend_ids =
          rundata.getParameters().getStrings("groupsend_to");
        if (groupsend_ids != null && groupsend_ids.length != 0) {
          for (int i = 0; i < groupsend_ids.length; i++) {
            AvzMGroupsend groupsend =
              Database.get(AvzMGroupsend.class, groupsend_ids[i]);
            AvzMUserGroupsend user_groupsend =
              Database.create(AvzMUserGroupsend.class);
            user_groupsend.setToAvzMGroupsend(groupsend);
            user_groupsend.setUserId(Integer.valueOf(user.getUserId()));
          }
        }

        // change end

        // アクセス権限
        ALAccessControlFactoryService aclservice =
          (ALAccessControlFactoryService) ((TurbineServices) TurbineServices
            .getInstance())
            .getService(ALAccessControlFactoryService.SERVICE_NAME);
        ALAccessControlHandler aclhandler =
          aclservice.getAccessControlHandler();
        aclhandler.insertDefaultRole(Integer.parseInt(user.getUserId()));

        Database.commit();

        // WebAPIとのDB同期
        if (!ALDataSyncFactoryService
          .getInstance()
          .getDataSyncHandler()
          .addUser(user)) {
          return false;
        }

      }

      // 一時的な添付ファイルの削除
      ALStorageService.deleteTmpFolder(
        ALEipUtils.getUserId(rundata),
        folderName);
    } catch (Exception e) {
      Database.rollback();
      String msg = "ユーザー情報の登録に失敗しました。";
      logger.error(msg, e);
      msgList.add(msg);
      return false;
    }
    return res;
  }

  /**
   * ユーザー更新
   * 
   * @param rundata
   *          JetSpeedランデータ
   * @param context
   *          JetSpeedコンテキスト
   * @param msgList
   *          エラーメッセージリスト
   * @return 処理結果(正常：true、異常:false)
   * @see com.aimluck.eip.common.ALAbstractFormData#loadFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  @Override
  protected boolean updateFormData(RunData rundata, Context context,
      List<String> msgList) {
    boolean res = true;
    try {
      // WebAPIのDBへ接続できるか確認
      if (!ALDataSyncFactoryService
        .getInstance()
        .getDataSyncHandler()
        .checkConnect()) {
        msgList.add("コントロールパネルWebAPIのデータベースの接続に失敗したため、処理は実行されませんでした。");
        return false;
      }
      // del by motegi start 部署・役職複数化対応
      // if (is_new_post) {
      // // 部署登録も同時に行う場合
      // res = post.insertFormData(rundata, context, msgList);
      // if (res) {
      // post_id.setValue(post.getPostId());
      // }
      // }
      // if (is_new_position && res) {
      // // 役職登録も同時に行う場合
      // res = position.insertFormData(rundata, context, msgList);
      // if (res) {
      // position_id.setValue(position.getPositionId());
      // }
      // }
      // del end
      if (res) {
        ALBaseUser user = AccountUtils.getBaseUser(rundata, context);
        if (user == null) {
          return false;
        }
        String oldDisabled = user.getDisabled();
        rundata.getParameters().setProperties(user);
        user.setLastAccessDate();

        if (!dontUpdatePasswd) {
          JetspeedSecurity.forcePassword(user, password.getValue());
        } else {
          Expression exp =
            ExpressionFactory.matchDbExp(TurbineUser.USER_ID_PK_COLUMN, user
              .getUserId());
          SelectQuery<TurbineUser> query =
            Database.query(TurbineUser.class, exp);
          List<TurbineUser> list = query.fetchList();
          if (list == null || list.size() == 0) {
            return false;
          }
          TurbineUser tuser = list.get(0);
          user.setPassword(tuser.getPasswordValue());
        }
        String strDisabled = user.getDisabled();
        // String strDisabled = disabled.getValue();
        user.setDisabled(strDisabled);
        if (!"T".equals(strDisabled)
          && "T".equals(oldDisabled)
          && JetspeedSecurity.isDisableAccountCheckEnabled()) {
          JetspeedSecurity.resetDisableAccountCheck(user.getUserName());
        }

        user.setInTelephone(in_telephone.getValue());
        if (!out_telephone1.getValue().equals("")
          && !out_telephone2.getValue().equals("")
          && !out_telephone3.getValue().equals("")) {
          user.setOutTelephone(new StringBuffer().append(
            out_telephone1.getValue()).append("-").append(
            out_telephone2.getValue()).append("-").append(
            out_telephone3.getValue()).toString());
        } else {
          user.setOutTelephone("");
        }

        if (!cellular_phone1.getValue().equals("")
          && !cellular_phone2.getValue().equals("")
          && !cellular_phone3.getValue().equals("")) {
          user.setCellularPhone(new StringBuffer().append(
            cellular_phone1.getValue()).append("-").append(
            cellular_phone2.getValue()).append("-").append(
            cellular_phone3.getValue()).toString());
        } else {
          user.setCellularPhone("");
        }
        user.setCellularMail(cellular_mail.getValue());
        // user.setCompanyId((int)company_id.getValue());
        // del by motegi start
        // user.setPositionId((int) position_id.getValue());
        user.setFirstNameKana(first_name_kana.getValue());
        user.setLastNameKana(last_name_kana.getValue());
        if (filebean != null) {
          if (filebean.getFileId() > 0) {
            // 顔写真を登録する．
            user.setPhoto(facePhoto);
          }
        } else {
          user.setPhoto(null);
        }

        user.setEmail(email.getValue());

        // add by motegi start
        user.setCelluarUId(cellular_uid.getValue());
        user.setCategory(category_name.getValue());
        user.setDisplayName(display_name.getValue());
        // add end

        if (is_admin.getValue() != null) {
          // is_adminの値が渡されなかった場合は、従来の設定を維持する。
          if (is_admin.getValue().equals("true")) {
            user.setPerm("isAdmin", true);
          } else {
            user.setPerm("isAdmin", false);
          }
        }

        // ユーザーを更新
        JetspeedSecurity.saveUser(user);

        // 部署を移動
        List<UserGroupLiteBean> postList_old =
          AccountUtils.getPostBeanList(Integer.parseInt(user.getUserId()));
        if (postList_old != null && postList_old.size() > 0) {
          // グループからユーザーを削除
          for (UserGroupLiteBean uglb : postList_old) {
            JetspeedSecurity.unjoinGroup(user.getUserName(), uglb.getGroupId());
          }
        }

        // change by motegi start 複数部署・役職対応
        // String[] groupNameList =
        // rundata.getParameters().getStrings("group_to");
        // if (groupNameList != null && groupNameList.length > 0) {
        // int size = groupNameList.length;
        // for (int i = 0; i < size; i++) {
        // // グループへユーザーを追加
        // JetspeedSecurity.joinGroup(user.getUserName(), groupNameList[i]);
        // }
        // }
        String[] post2_ids = rundata.getParameters().getStrings("post2_id[]");
        String[] position_ids =
          rundata.getParameters().getStrings("position_id[]");
        final String defaultRole = "user";
        if (post2_ids != null && post2_ids.length != 0) {
          for (int i = 0; i < post2_ids.length; i++) {
            JetspeedSecurity.joinGroup(
              user.getUserName(),
              post2_ids[i],
              defaultRole,
              position_ids[i]);
          }
        }

        // ユーザー役割情報を一旦削除する。
        String deleteAvzMUserRoleSql =
          "DELETE FROM avz_m_user_role WHERE USER_ID = #bind($userId 'INTEGER')";
        Database.sql(AvzMUserRole.class, deleteAvzMUserRoleSql).param(
          "userId",
          user.getUserId()).execute();

        String[] role_ids = rundata.getParameters().getStrings("role_to");
        if (role_ids != null && role_ids.length != 0) {
          for (int i = 0; i < role_ids.length; i++) {
            AvzMRole role = Database.get(AvzMRole.class, role_ids[i]);
            AvzMUserRole user_role = Database.create(AvzMUserRole.class);
            user_role.setToAvzMRole(role);
            user_role.setUserId(Integer.valueOf(user.getUserId()));
          }
        }

        // グループ送信情報を一旦削除する。
        String deleteAvzMUserGroupsendSql =
          "DELETE FROM avz_m_user_groupsend WHERE USER_ID = #bind($userId 'INTEGER')";
        Database
          .sql(AvzMUserGroupsend.class, deleteAvzMUserGroupsendSql)
          .param("userId", user.getUserId())
          .execute();

        // グループ送信情報登録
        String[] groupsend_ids =
          rundata.getParameters().getStrings("groupsend_to");
        if (groupsend_ids != null && groupsend_ids.length != 0) {
          for (int i = 0; i < groupsend_ids.length; i++) {
            AvzMGroupsend groupsend =
              Database.get(AvzMGroupsend.class, groupsend_ids[i]);
            AvzMUserGroupsend user_groupsend =
              Database.create(AvzMUserGroupsend.class);
            user_groupsend.setToAvzMGroupsend(groupsend);
            user_groupsend.setUserId(Integer.valueOf(user.getUserId()));
          }
        }
        // change end

        ALBaseUser currentUser = (ALBaseUser) rundata.getUser();

        // もし編集者自身が自分の情報を修正していた場合には
        // セッション情報も書き換える。
        if (currentUser.getUserName().equals(user.getUserName())) {
          currentUser.setPassword(user.getPassword());
          currentUser.setFirstName(user.getFirstName());
          currentUser.setLastName(user.getLastName());
          currentUser.setEmail(user.getEmail());
          currentUser.setInTelephone(user.getInTelephone());
          currentUser.setOutTelephone(user.getOutTelephone());
          currentUser.setCellularPhone(user.getCellularPhone());
          currentUser.setCellularMail(user.getCellularMail());
          currentUser.setPositionId(user.getPositionId());
          try {
            currentUser.setPostId(user.getPostId());
          } catch (NullPointerException e) {
          }
          currentUser.setFirstNameKana(user.getFirstNameKana());
          currentUser.setLastNameKana(user.getLastNameKana());
        }

        // add by motegi start
        Database.commit();
        // add end

        // WebAPIとのDB同期
        if (!ALDataSyncFactoryService
          .getInstance()
          .getDataSyncHandler()
          .updateUser(user)) {
          return false;
        }
      }

      // 一時的な添付ファイルの削除
      ALStorageService.deleteTmpFolder(
        ALEipUtils.getUserId(rundata),
        folderName);
    } catch (Exception e) {
      Database.rollback();
      String msg = "ユーザー情報の更新に失敗しました。";
      logger.error(msg, e);
      msgList.add(msg);
      return false;
    }
    return res;
  }

  /**
   * 『ユーザー』を無効化します。 <BR>
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * 
   */
  public boolean disableFormData(RunData rundata, Context context,
      List<String> msgList) {
    try {
      if (!doCheckSecurity(rundata, context)) {
        return false;
      }
      // WebAPIのDBへ接続できるか確認
      if (!ALDataSyncFactoryService
        .getInstance()
        .getDataSyncHandler()
        .checkConnect()) {
        msgList.add("コントロールパネルWebAPIのデータベースの接続に失敗したため、処理は実行されませんでした。");
        return false;
      }
      String user_name =
        ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);

      if (user_name == null || "".equals(user_name)) {
        return false;
      }

      SelectQuery<TurbineUser> query = Database.query(TurbineUser.class);
      Expression exp =
        ExpressionFactory.matchExp(TurbineUser.LOGIN_NAME_PROPERTY, user_name);
      query.setQualifier(exp);
      List<TurbineUser> list = query.fetchList();

      if (list == null || list.size() == 0) {
        return false;
      }

      TurbineUser target_user = list.get(0);

      if (target_user.getLoginName().equals(rundata.getUser().getUserName())) {
        msgList.add("ログイン中のユーザを無効にすることは出来ません。");
        return false;
      }

      if (ALEipUtils.isAdmin(target_user.getUserId())
        && !AccountUtils.isAdminDeletable()) {
        msgList.add("ユーザー『 <span class='em'>"
          + target_user.getLoginName()
          + "</span> 』は管理者権限を持っているため、無効にできません。<br />最低でも"
          + Integer.valueOf(ALConfigService
            .get(Property.MINIMUM_ADMINISTRATOR_USER_COUNT))
          + " 人の管理者権限を持ったユーザーが必要です。");
        return false;
      }

      target_user.setDisabled("N");

      // ワークフロー自動承認
      AccountUtils.acceptWorkflow(target_user.getUserId());

      Database.commit();

      // WebAPIとのDB同期
      String[] user_name_list = { user_name };
      if (!ALDataSyncFactoryService
        .getInstance()
        .getDataSyncHandler()
        .multiDisableUser(user_name_list, user_name_list.length)) {
        return false;
      }

    } catch (Exception e) {
      Database.rollback();
      String msg = "ユーザー情報の無効化に失敗しました。";
      logger.error(msg, e);
      msgList.add(msg);
      return false;
    }
    return true;
  }

  /**
   * 『ユーザー』を有効化します。 <BR>
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * 
   */
  public boolean enableFormData(RunData rundata, Context context,
      List<String> msgList) {
    try {
      if (!doCheckSecurity(rundata, context)) {
        return false;
      }
      // WebAPIのDBへ接続できるか確認
      if (!ALDataSyncFactoryService
        .getInstance()
        .getDataSyncHandler()
        .checkConnect()) {
        msgList.add("コントロールパネルWebAPIのデータベースの接続に失敗したため、処理は実行されませんでした。");
        return false;
      }
      String user_name =
        ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);

      if (user_name == null || "".equals(user_name)) {
        return false;
      }

      SelectQuery<TurbineUser> query = Database.query(TurbineUser.class);
      Expression exp =
        ExpressionFactory.matchExp(TurbineUser.LOGIN_NAME_PROPERTY, user_name);
      query.setQualifier(exp);
      List<TurbineUser> list = query.fetchList();

      if (list == null || list.size() == 0) {
        return false;
      }

      (list.get(0)).setDisabled("F");
      Database.commit();

      // WebAPIとのDB同期
      String[] user_name_list = { user_name };
      if (!ALDataSyncFactoryService
        .getInstance()
        .getDataSyncHandler()
        .multiEnableUser(user_name_list, user_name_list.length)) {
        return false;
      }

    } catch (Exception e) {
      Database.rollback();
      logger.error("Exception", e);
      return false;
    }
    return true;
  }

  /**
   * ユーザー削除
   * 
   * @param rundata
   *          JetSpeedランデータ
   * @param context
   *          JetSpeedコンテキスト
   * @param msgList
   *          エラーメッセージリスト
   * @return 処理結果(正常：true、異常:false)
   * @see com.aimluck.eip.common.ALAbstractFormData#loadFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  @Override
  protected boolean deleteFormData(RunData rundata, Context context,
      List<String> msgList) {

    // add by motegi start
    // 標準のトランザクション（オートコミット）
    Transaction baseTx = Transaction.getThreadTransaction();

    DataContext dataContext = DataContext.getThreadDataContext();

    // 自己管理トランザクション
    Transaction tx =
      Transaction.internalTransaction(DataContext
        .getThreadDataContext()
        .getParentDataDomain()
        .getTransactionDelegate());

    // 標準のトランザクションを自己管理トランザクションに置き換えます。
    Transaction.bindThreadTransaction(tx);
    // add end

    try {

      // トランザクション開始
      // add by motegi start
      tx.begin();
      // add end

      // WebAPIのDBへ接続できるか確認
      logger.debug("deleteFormData");
      if (!ALDataSyncFactoryService
        .getInstance()
        .getDataSyncHandler()
        .checkConnect()) {
        msgList.add("コントロールパネルWebAPIのデータベースの接続に失敗したため、処理は実行されませんでした。");
        return false;
      }
      logger.debug("enddeleteFormData");
      String user_name =
        ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);

      if (user_name == null) {
        return false;
      }

      // ユーザーを論理削除
      TurbineUser user =
        Database.get(
          TurbineUser.class,
          TurbineUser.LOGIN_NAME_COLUMN,
          user_name);

      if (user.getLoginName().equals(rundata.getUser().getUserName())) {
        msgList.add("ログイン中のユーザを削除することは出来ません。");
        return false;
      }

      if (ALEipUtils.isAdmin(user.getUserId())
        && !AccountUtils.isAdminDeletable()) {
        msgList.add("ユーザー『 <span class='em'>"
          + user.getLoginName()
          + "</span> 』は管理者権限を持っているため、削除できません。<br />最低でも"
          + Integer.valueOf(ALConfigService
            .get(Property.MINIMUM_ADMINISTRATOR_USER_COUNT))
          + " 人の管理者権限を持ったユーザーが必要です。");
        return false;
      }

      // ユーザーの削除を行なう
      // change by motegi start
      // user.setPositionId(Integer.valueOf(0));
      // user.setDisabled("T");
      //
      // // ユーザーIDを取得する
      // SelectQuery<TurbineUser> query = Database.query(TurbineUser.class);
      // Expression exp1 =
      // ExpressionFactory.matchExp(TurbineUser.LOGIN_NAME_PROPERTY, user_name);
      // query.setQualifier(exp1);
      // List<TurbineUser> list3 = query.fetchList();
      //
      // int userNum = list3.size();
      // if (userNum != 1) {
      // return false;
      // }
      // TurbineUser deleteuser = list3.get(0);
      // String userId;
      // userId = deleteuser.getUserId().toString();
      //
      // // 対象ユーザのユーザーグループロールをすべて削除する
      // SelectQuery<TurbineUserGroupRole> query2 =
      // Database.query(TurbineUserGroupRole.class);
      // Expression exp2 =
      // ExpressionFactory.matchExp(
      // TurbineUserGroupRole.TURBINE_USER_PROPERTY,
      // userId);
      // query2.setQualifier(exp2);
      // List<TurbineUserGroupRole> list4 = query2.fetchList();
      //
      // TurbineUserGroupRole ugr = null;
      // for (int i = 0; i < list4.size(); i++) {
      // ugr = list4.get(i);
      // Database.delete(ugr);
      // }
      //
      // // ToDoを削除する
      // String sql4 = "DELETE FROM eip_t_todo WHERE USER_ID = '" + userId +
      // "'";
      // Database.sql(EipTTodo.class, sql4).execute();
      //
      // String sql5 =
      // "DELETE FROM eip_t_todo_category WHERE USER_ID = '" + userId + "'";
      // Database.sql(EipTTodoCategory.class, sql5).execute();
      //
      // // ブログを削除する
      // String sql6 = "DELETE FROM eip_t_blog WHERE OWNER_ID = '" + userId +
      // "'";
      // Database.sql(EipTBlog.class, sql6).execute();
      //
      // // ブログの足跡を削除する
      // String sql7 =
      // "DELETE FROM eip_t_blog_footmark_map WHERE USER_ID = '" + userId + "'";
      // Database.sql(EipTBlogFootmarkMap.class, sql7).execute();
      //
      // // ワークフロー自動承認
      // AccountUtils.acceptWorkflow(deleteuser.getUserId());
      //
      // // ソーシャルアプリ関連データ削除
      // ALApplicationService.deleteUserData(user_name);
      AccountUtils.deleteUser(user, msgList);
      // change end

      // change by motegi start
      // Database.commit();
      dataContext.commitChanges();

      // 他のユーザの順番を変更する．
      // change by motegi start
      // SelectQuery<EipMUserPosition> p_query =
      // Database.query(EipMUserPosition.class);
      // p_query.orderAscending(EipMUserPosition.POSITION_PROPERTY);
      // List<EipMUserPosition> userPositions = p_query.fetchList();
      // if (userPositions != null && userPositions.size() > 0) {
      // EipMUserPosition userPosition = null;
      // int index = -1;
      // int size = userPositions.size();
      // for (int i = 0; i < size; i++) {
      // userPosition = userPositions.get(i);
      // if (userId.equals(userPosition.getTurbineUser().toString())) {
      // // 指定したユーザを削除する．
      // Database.delete(userPosition);
      // index = i;
      // break;
      // }
      // }
      // if (index >= 0) {
      // for (int i = index + 1; i < size; i++) {
      // userPosition = userPositions.get(i);
      // userPosition.setPosition(Integer.valueOf(i));
      // }
      // }
      // }
      SelectQuery<EipMUserPosition> p_query =
        Database.query(EipMUserPosition.class);
      p_query.orderAscending(EipMUserPosition.POSITION_PROPERTY);
      List<EipMUserPosition> entityPositions = p_query.fetchList();

      if (entityPositions != null && entityPositions.size() > 0) {
        int size = entityPositions.size();
        for (int i = 0; i < size; i++) {
          EipMUserPosition entityPosition = entityPositions.get(i);
          entityPosition.setPosition(Integer.valueOf(i + 1));
        }
      }
      // change end

      // del by motegi start
      // // PSMLを削除
      // JetspeedUser juser =
      // JetspeedSecurity.getUser(new UserNamePrincipal(user_name));
      // PsmlManager.removeUserDocuments(juser);
      //
      // // ユーザー名の先頭に"dummy_userid_"を追加
      // String dummy_user_name =
      // ALEipUtils.dummy_user_head + userId + "_" + user_name;
      // user.setLoginName(dummy_user_name);
      // del end

      Database.commit();

      // WebAPIとのDB同期
      if (!ALDataSyncFactoryService
        .getInstance()
        .getDataSyncHandler()
        .deleteUser(user_name)) {
        return false;
      }

    } catch (Exception ex) {
      Database.rollback();
      String msg = "ユーザー情報の削除に失敗しました。";
      logger.error(msg, ex);
      msgList.add(msg);
      return false;
    } finally {
      // 自己管理トランザクションを標準のトランザクションに戻します。
      Transaction.bindThreadTransaction(baseTx);
    }
    return true;
  }

  /**
   * 携帯メールアドレスを取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getCellularMail() {
    return cellular_mail;
  }

  /**
   * 会社IDを取得します。 <BR>
   * 
   * @return
   */
  public ALNumberField getCompanyId() {
    return company_id;
  }

  /**
   * アカウント有効/無効フラグを取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getDisabled() {
    return disabled;
  }

  /**
   * メールアドレスを取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getEmail() {
    return email;
  }

  /**
   * フリガナ（名）を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getFirstNameKana() {
    return first_name_kana;
  }

  /**
   * 名前（名）を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getFirstName() {
    return firstname;
  }

  /**
   * 電話番号（内線）を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getInTelephone() {
    return in_telephone;
  }

  /**
   * フリガナ（姓）を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getLastNameKana() {
    return last_name_kana;
  }

  /**
   * 名前（姓）を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getLastName() {
    return lastname;
  }

  /**
   * 携帯電話番号を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getCellularPhone1() {
    return cellular_phone1;
  }

  /**
   * 携帯電話番号を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getCellularPhone2() {
    return cellular_phone2;
  }

  /**
   * 携帯電話番号を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getCellularPhone3() {
    return cellular_phone3;
  }

  /**
   * 電話番号を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getOutTelephone1() {
    return out_telephone1;
  }

  /**
   * 電話番号を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getOutTelephone2() {
    return out_telephone2;
  }

  /**
   * 電話番号を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getOutTelephone3() {
    return out_telephone3;
  }

  /**
   * パスワードを取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getPassword() {
    return password;
  }

  /**
   * パスワード2を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getPassword2() {
    return password2;
  }

  /**
   * 役職IDを取得します。 <BR>
   * 
   * @return
   */
  public ALNumberField getPositionId() {
    return position_id;
  }

  /**
   * 部署IDを取得します。 <BR>
   * 
   * @return
   */
  public ALNumberField getPostId() {
    return post_id;
  }

  /**
   * ユーザー名を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getUserName() {
    return username;
  }

  /**
   * 役職リストを取得します。 <BR>
   * 
   * @return
   */
  public List<ALEipPosition> getPositionList() {
    return positionList;
  }

  /**
   * 
   * @return
   */
  public List<UserGroupLiteBean> getPostList() {
    return postList;
  }

  /**
   * 部署１リスト取得
   * 
   * @return 部署１リスト
   */
  // public Map<Integer, ALEipPost> getPostMap() {
  public List<ALEipPost> getPostMap() {
    // change by motegi start 部署階層化対応
    // return ALEipManager.getInstance().getPostMap();
    return ALEipUtils.getPostMap(false, false);
    // change end;
  }

  /**
   * 
   * @return
   */
  public Map<Integer, ALEipPosition> getPositionMap() {
    return ALEipManager.getInstance().getPositionMap();
  }

  /**
   * 
   * @return
   */
  public AccountPostFormData getPost() {
    return post;
  }

  /**
   * 
   * @return
   */
  public AccountPositionFormData getPosition() {
    return position;
  }

  /**
   * 
   * @return
   */
  public boolean isNewPost() {
    return is_new_post;
  }

  /**
   * 
   * @return
   */
  public boolean isNewPosition() {
    return is_new_position;
  }

  public FileuploadLiteBean getFileBean() {
    return filebean;
  }

  public List<FileuploadLiteBean> getAttachmentFileNameList() {
    if (filebean == null) {
      return null;
    }
    ArrayList<FileuploadLiteBean> list = new ArrayList<FileuploadLiteBean>();
    list.add(filebean);
    return list;
  }

  public String getFolderName() {
    return folderName;
  }

  /**
   * @return is_admin
   */
  public ALStringField getIsAdmin() {
    return is_admin;
  }

  /**
   * @return isSkipUsernameValidation
   */
  public boolean isSkipUsernameValidation() {
    return isSkipUsernameValidation;
  }

  public void setSkipUsernameValidation(boolean isSkipUsernameValidation) {
    this.isSkipUsernameValidation = isSkipUsernameValidation;
  }

  // add start
  /**
   * 端末固有番号取得
   * 
   * @return 端末固有番号
   */
  public ALStringField getCellularUid() {
    return cellular_uid;
  }

  /**
   * 職種取得
   * 
   * @return 職種
   */
  public ALStringField getCategoryName() {
    return category_name;
  }

  /**
   * 表示名取得
   * 
   * @return 表示名
   */
  public ALStringField getDisplayName() {
    return display_name;
  }

  // add by motegi start 複数部署・役職対応
  /**
   * 部署・役職リスト取得
   * 
   * @return 部署・役職リスト
   */
  public List<UserGroupPositionLiteBean> getPostPositionList() {
    return post_position_list;
  }

  // add by motegi
  /**
   * 役割リスト取得
   * 
   * @return 役割リスト
   */
  public List<ALEipRole> getRoleList() {
    return role_list;
  }

  // add by motegi
  /**
   * グループ送信リスト取得
   * 
   * @return グループ送信リスト
   */
  public List<ALEipGroupSend> getGroupSendList() {
    return groupsend_list;
  }

}
