/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2008 Aimluck,Inc.
 * http://aipostyle.com/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.aimluck.eip.document;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.cayenne.DataObjectUtils;
import org.apache.cayenne.DataRow;
import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.SQLTemplate;
import org.apache.cayenne.query.SelectQuery;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.commons.field.ALDateTimeField;
import com.aimluck.commons.field.ALNumberField;
import com.aimluck.commons.field.ALStringField;
import com.aimluck.eip.document.util.DocumentUtils;
import com.aimluck.eip.cayenne.om.portlet.EipTWorkflowRequest;
import com.aimluck.eip.cayenne.om.portlet.EipTWorkflowRequestMap;
import com.aimluck.eip.cayenne.om.portlet.EipTWorkflowRoute;
import com.aimluck.eip.cayenne.om.portlet.ImwTDocumentFile;
import com.aimluck.eip.cayenne.om.portlet.ImwTDocumentFileMap;
import com.aimluck.eip.cayenne.om.portlet.ImwTDocumentFolder;
import com.aimluck.eip.cayenne.om.portlet.ImwTDocumentFolderMap;
import com.aimluck.eip.cayenne.om.portlet.ImwTDocumentRelationMap;
import com.aimluck.eip.cayenne.om.portlet.ImwTDocumentRequestMap;
import com.aimluck.eip.cayenne.om.security.TurbineUser;
import com.aimluck.eip.cayenne.om.security.TurbineGroup;
import com.aimluck.eip.common.ALAbstractFormData;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALEipUser;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.common.ALPermissionException;
import com.aimluck.eip.fileupload.beans.FileuploadLiteBean;
import com.aimluck.eip.fileupload.util.FileuploadUtils;
import com.aimluck.eip.libdocument.util.LibDocumentUtils;
import com.aimluck.eip.modules.actions.common.ALAction;
import com.aimluck.eip.modules.screens.DocumentFileRawScreen;
import com.aimluck.eip.orm.DatabaseOrmService;
import com.aimluck.eip.services.accessctl.ALAccessControlConstants;
import com.aimluck.eip.services.eventlog.ALEventlogConstants;
import com.aimluck.eip.services.eventlog.ALEventlogFactoryService;
import com.aimluck.eip.util.ALEipUtils;
import com.aimluck.eip.workflow.util.WorkflowUtils;
import com.aimluck.eip.cayenne.om.portlet.ImwTDocumentFileMap;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import jp.co.imtt.ImwareLogger;

import com.aimluck.eip.document.util.RelationuploadUtils;
import com.aimluck.eip.document.beans.RelationuploadLiteBean;
import com.aimluck.eip.document.common.DocumentConstants;

/**
 * 文書管理のファイルフォームデータを管理するクラス <BR>
 *
 */
public class DocumentFileFormData extends ALAbstractFormData {

  /** logger */
  private static final JetspeedLogger logger = JetspeedLogFactoryService
      .getLogger(DocumentFileFormData.class.getName());
  
  // private static final ImwareLogger logger = new ImwareLogger("document");

  /** ファイルID */
  private int file_id;

  /** フォルダ ID */
  private ALNumberField folder_id;

  /** ファイルタイトル */
  private ALStringField file_title;

  /** ファイル名 */
  private ALStringField file_name;

  /** 関連文書名 */
  private ALStringField relation_name;

  /** ファイルサイズ */
  private ALNumberField file_size;

  /** メモ */
  private ALStringField note;

  /** フォルダ情報一覧 */
  private ArrayList folder_hierarchy_list;

  /** 選択されたフォルダ情報 */
  private FolderInfo selected_folderinfo = null;

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

  /** アクセス権限のフォームを表示するか */
  private boolean show_acl_form = true;

  private String fileid = null;

  private String org_id = null;

  private DataContext dataContext;

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

  /** 関連文書ファイルリスト */
  private List relationuploadList = null;

  /** 関連文書ファイルリスト（初期表示用） */
  private List initRelationList = null;

  /** Validate用(添付ファイルID) */
  private String[] fileids;

  private RunData rundata;

  /** バージョン */
  private ALStringField fileRev;

  /** 公開終了日 */
  private Calendar open_end_date;

  /** 保存終了日 */
  private Calendar save_end_date;

  /** チェックインコメント */
  private ALStringField checkinComment;

  /** アクセス権限 */
  /** メンバー選択が必要かどうか */
  private boolean is_member_read;

  private boolean is_member_edit;

  /** 閲覧権限メンバーグループリスト */
  private ArrayList memberReadGroupList;

  /** 閲覧権限メンバーユーザーリスト */
  private ArrayList memberReadUserList;

  /** 編集権限メンバーグループリスト */
  private ArrayList memberEditGroupList;

  /** 編集権限メンバーユーザーリスト */
  private ArrayList memberEditUserList;

  /** 初期表示用 閲覧権限メンバーグループリスト */
  private ArrayList initReadGroupList;

  /** 初期表示用　閲覧権限メンバーユーザーリスト */
  private ArrayList initReadUserList;

  /** 初期表示用　編集権限メンバーグループリスト */
  private ArrayList initEditGroupList;

  /** 初期表示用　編集権限メンバーユーザーリスト */
  private ArrayList initEditUserList;

  /** アクセス権限フラグ */
  private ALNumberField access_flag;

  /** ログインユーザー */
  //private ALEipUser login_user;
  /** 文書ID */
  private Integer docId = null;

  /** ログインユーザが文書管理者かどうか */
  private boolean isDocAdmin;

  /** 申請経路の選択 */
  private boolean is_saved_route;

  /** 申請先一覧 */
  private ArrayList workflowMemberList;

  /** 申請経路一覧 */
  private List routeList;

  /** 申請経路ID */
  private ALNumberField route_id;

  private ALStringField route;

  /** 申請先ユーザIDリスト */
  private ALStringField positions_workflow;
  
  /** 再申請かどうか */
  private boolean isDocReqAgain;
  
  /** 文書ファイル */
  private ImwTDocumentFile docFile, oldDocFile;

  /**
   *
   * @param action
   * @param rundata
   * @param context
   * @see com.aimluck.eip.common.ALAbstractFormData#init(com.aimluck.eip.modules.actions.common.ALAction,
   *      org.apache.turbine.util.RunData, org.apache.velocity.context.Context)
   */
  public void init(ALAction action, RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {
    super.init(action, rundata, context);

    // 自ポートレットからのリクエストであれば、パラメータを展開しセッションに保存する。
    if (ALEipUtils.isMatch(rundata, context)) {
      // ENTITY ID
      if (rundata.getParameters().containsKey(DocumentUtils.KEY_FOLDER_ID)) {
        ALEipUtils.setTemp(rundata, context, DocumentUtils.KEY_FOLDER_ID,
            rundata.getParameters().getString(DocumentUtils.KEY_FOLDER_ID));
      }
    }

    org_id = DatabaseOrmService.getInstance().getOrgId(rundata);
    dataContext = DatabaseOrmService.getInstance().getDataContext();
    this.rundata = rundata;

    String tmpfid = ALEipUtils.getTemp(rundata, context,
        DocumentUtils.KEY_FOLDER_ID);
    int fid = DocumentUtils.ROOT_FODLER_ID;
    if (tmpfid != null && !"".equals(tmpfid)) {
      try {
        fid = Integer.parseInt(tmpfid);
      } catch (Exception e) {
        fid = DocumentUtils.ROOT_FODLER_ID;
      }
    }

    folder_hierarchy_list = DocumentUtils.getFolderList();
    DocumentUtils.setFolderVisibleForForm(folder_hierarchy_list, rundata);

    int size = folder_hierarchy_list.size();
    for (int i = 0; i < size; i++) {
      FolderInfo info = (FolderInfo) folder_hierarchy_list.get(i);
      if (info.getFolderId() == fid) {
        selected_folderinfo = info;
      }
    }

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

    fileids = rundata.getParameters().getStrings("attachments");

    // 文書ファイル取得
    this.docFile = DocumentUtils.getImwTDocumentFile(rundata, context);
    
    // 文書ID取得
    if(this.docFile == null){
      this.docId = null;
    } else {
      this.docId = docFile.getDocId();
    }
    
    // 旧文書ファイル取得
    this.oldDocFile = LibDocumentUtils.getLastDoc(this.docId);
    
    // ログインユーザが文書管理者かどうか
    this.isDocAdmin = DocumentUtils.isDocAdmin(rundata);

    // 再申請かどうか
    this.isDocReqAgain = DocumentUtils.isDocReqAgain(this.docId);
    
    //login_user = ALEipUtils.getALEipUser(rundata);
  }

  /**
   * 各フィールドを初期化します。 <BR>
   *
   * @see com.aimluck.eip.common.ALData#initField()
   */
  public void initField() {

    // フォルダ ID
    folder_id = new ALNumberField();
    folder_id.setFieldName("フォルダ");
    folder_id.setNotNull(true);
    folder_id.setValue(0);
    // ファイルタイトル
    file_title = new ALStringField();
    file_title.setFieldName("タイトル");
    file_title.setTrim(true);
    // ファイル名
    file_name = new ALStringField();
    file_name.setFieldName("ファイル名");
    file_name.setTrim(true);

    // 関連文書名
    relation_name = new ALStringField();
    relation_name.setFieldName("関連文書名");
    relation_name.setTrim(true);

    // ファイルサイズ
    file_size = new ALNumberField();
    file_size.setFieldName("ファイルサイズ");
    // メモ
    note = new ALStringField();
    note.setFieldName("メモ");
    note.setTrim(true);
    // バージョン
    fileRev = new ALStringField();
    fileRev.setFieldName("バージョン");

    //公開終了日
    open_end_date = null;

    //保存終了日
    save_end_date = null;

    //　チェックインコメント
    checkinComment = new ALStringField();
    checkinComment.setFieldName("チェックインコメント");
    checkinComment.setTrim(true);

    // アクセス権限フラグ
    access_flag = new ALNumberField();
    access_flag.setFieldName("アクセス権限");
    access_flag.setValue(0);

    fileuploadList = new ArrayList();
    relationuploadList = new ArrayList();
    initRelationList = new ArrayList();

    // 閲覧権限メンバーグループリスト
    memberReadGroupList = new ArrayList();

    // 閲覧権限メンバーユーザーリスト
    memberReadUserList = new ArrayList();

    // 編集権限メンバーグループリスト
    memberEditGroupList = new ArrayList();

    // 編集権限メンバーユーザーリスト
    memberEditUserList = new ArrayList();

    // 初期表示用　閲覧権限メンバーグループリスト
    initReadGroupList = new ArrayList();

    // 初期表示用　閲覧権限メンバーユーザーリスト
    initReadUserList = new ArrayList();

    // 初期表示用　編集権限メンバーグループリスト
    initEditGroupList = new ArrayList();

    // 初期表示用　編集権限メンバーユーザーリスト
    initEditUserList = new ArrayList();

    // 申請経路ID
    route_id = new ALNumberField();
    route_id.setFieldName("申請経路");
    // 申請経路
    route = new ALStringField();

    // 申請先一覧
    workflowMemberList = new ArrayList();

    // 申請先のリスト
    positions_workflow = new ALStringField();
    positions_workflow.setFieldName("ユーザ名リスト");
    positions_workflow.setTrim(true);
    
    // デフォルトの申請経路があれば設定する。
    EipTWorkflowRoute docRoute = DocumentUtils.getDocRoute();
    if(docRoute != null){
      is_saved_route = true;
      route_id.setValue(docRoute.getRouteId());
      route.setValue(docRoute.getRoute());
      DocumentUtils.setWorkflowMember(workflowMemberList, route.getValue());
    }
  }

  /**
   *
   * @param rundata
   * @param context
   */
  public void loadRouteList(RunData rundata, Context context) {
    routeList = WorkflowUtils.loadRouteList(rundata, context);
  }

  /**
   * 閲覧・編集権限の配列を初期化します。 <BR>
   *
   * @see com.aimluck.eip.common.ALData#initField()
   */
  public void initMemberList(RunData rundata, Context context) {

    SelectQuery query;
    Expression exp;

    query = new SelectQuery(TurbineUser.class);
    exp = ExpressionFactory.matchDbExp(TurbineUser.USER_ID_PK_COLUMN,
        ALEipUtils.getALEipUser(rundata).getUserId().getValue());
    query.setQualifier(exp);
    initReadUserList.addAll(DocumentUtils.getUsersFromSelectQuery(query));
    initEditUserList.addAll(DocumentUtils.getUsersFromSelectQuery(query));

  }

  /*
   * @see com.aimluck.eip.common.ALAbstractFormData#setFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  protected boolean setFormData(RunData rundata, Context context,
      ArrayList msgList) throws ALPageNotFoundException, ALDBErrorException {

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

    if (res) {
      if (!rundata.getParameters().containsKey(DocumentUtils.KEY_FOLDER_ID)) {
        try {
          folder_id.setValue(selected_folderinfo.getFolderId());
        } catch (Exception e) {
          folder_id.setValue(DocumentUtils.ROOT_FODLER_ID);
        }
      }

      if (ALEipConstants.MODE_UPDATE.equals(getMode())) {
        fileid = ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);
      }

      if (ALEipConstants.MODE_CHECKIN.equals(getMode())) {
        fileid = ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);
      }

    }

    try {
      fileuploadList = FileuploadUtils.getFileuploadList(rundata);
      FileuploadLiteBean filebean = null;
      if (fileuploadList != null) {
        // 新規にアップロードしたデータをつめる
        filebean = (FileuploadLiteBean) fileuploadList.get(0);
        file_name.setValue(filebean.getFileName());
      }
      // 再申請かつファイルを変更しない場合、前回のファイル名をセット
      else if (fileids != null && "I".equals(fileids[0])) {
        ImwTDocumentFile file = DocumentUtils.getImwTDocumentFile(rundata,
            context);
        if (file != null) {
          file_name.setValue(file.getFileName());
        }
      }

      // 関連文書
      relationuploadList = RelationuploadUtils.getRelationuploadList(rundata);

      // ファイル追加：障害３　関連文書を削除して空にした場合にファイル追加できない問題の対応
      // 表題の場合、リストがNULLにならないが、get(0)に失敗するためエラーになる。
      // relation_name は未使用のため処理を削除する。

      /*
      RelationuploadLiteBean relationbean = null;
                
      if (relationuploadList != null) {
        // 新規にアップロードしたデータをつめる
        relationbean = (RelationuploadLiteBean) relationuploadList.get(0);
        relation_name.setValue(relationbean.getFileName());
      }
       */

      /* チェックインコメントを画面から取得 */
      String checkinComment = rundata.getParameters().get("checkinComment");
      this.checkinComment.setValue(checkinComment);
      //System.out.println("checkinComment = [" + checkinComment + "]");  

      /* バージョンを画面から取得 */
      String fileRev = rundata.getParameters().get("fileRev");
      this.fileRev.setValue(fileRev);
      //System.out.println("fileRev = [" + fileRev + "]");  

      /* 公開終了日を画面から取得 */
      DateFormat df = new SimpleDateFormat("yyyy/M/d");
      String str_open_end_date = rundata.getParameters().get("open_end_date");
      String check = rundata.getParameters().get("open_end_date_check");
      if (str_open_end_date != null && check == null) {
        open_end_date = Calendar.getInstance();
        open_end_date.setTime(df.parse(str_open_end_date));
      }
      //System.out.println("open_end_date = " + rundata.getParameters().get("open_end_date"));
      //System.out.println("open_end_date_check = " + rundata.getParameters().get("open_end_date_check"));
      //System.out.println("open_end_date_flag = " + rundata.getParameters().get("open_end_date_flag"));

      /* 保存終了日を画面から取得 */
      String str_save_end_date = rundata.getParameters().get("save_end_date");
      check = rundata.getParameters().get("save_end_date_check");
      if (str_save_end_date != null && check == null) {
        save_end_date = Calendar.getInstance();
        save_end_date.setTime(df.parse(str_save_end_date));
      }

      /* 閲覧メンバー選択が必要か */
      if ("checked".equals(rundata.getParameters().get("read_all"))) {
        is_member_read = false;
      } else {
        is_member_read = true;
      }

      /* 編集メンバー選択が必要か */
      if ("checked".equals(rundata.getParameters().get("edit_all"))) {
        is_member_edit = false;
      } else {
        is_member_edit = true;
      }

      /* 閲覧権限メンバーリストを画面から取得し、グループとユーザに振り分け */
      if (is_member_read) {
        DocumentUtils.separateGroupAndUser(rundata, "member_read",
            memberReadGroupList, memberReadUserList);
      }

      /* 編集権限メンバーリストを画面から取得し、グループとユーザに振り分け */
      if (is_member_edit) {
        DocumentUtils.separateGroupAndUser(rundata, "member_edit",
            memberEditGroupList, memberEditUserList);
      }

      // 申請・再申請の場合
      if (DocumentConstants.MODE_REQUEST_INSERT.equals(getMode())
          || DocumentConstants.MODE_REQAGAIN_INSERT.equals(getMode())
          || DocumentConstants.MODE_REQUEST_CHECKIN.equals(getMode())
          || DocumentConstants.MODE_REQAGAIN_CHECKIN.equals(getMode())
          || DocumentConstants.MODE_REQUEST_CHECKOUT.equals(getMode())
          || DocumentConstants.MODE_REQUEST_CHECKOUT_CANCEL.equals(getMode())
          || DocumentConstants.MODE_REQUEST_DELETE.equals(getMode())
      ){
        // 申請経路の選択オンオフ
        is_saved_route = rundata.getParameters().getBoolean("is_saved_route");

        // 申請経路のユーザ
        DocumentUtils.setWorkflowMemberFromRunData(rundata, workflowMemberList,
            is_saved_route, route_id.getValue());
      }

    } catch (Exception ex) {
      logger.error("Exception", ex);
    }

    return res;
  }

  /**
   * ファイルの各フィールドに対する制約条件を設定します。 <BR>
   *
   * @see com.aimluck.eip.common.ALAbstractFormData#setValidator()
   */
  protected void setValidator() {
    // ファイルタイトル必須項目
    file_title.setNotNull(true);
    // ファイルタイトルの文字数制限
    file_title.limitMaxLength(128);
    // ファイル名必須項目
    file_name.setNotNull(true);
    // ファイル名の文字数制限
    file_name.limitMaxLength(128);
    // メモの文字数制限
    note.limitMaxLength(1000);
    // チェックインコメントの文字数制限
    checkinComment.limitMaxLength(1000);
    // バージョン必須項目
    fileRev.setNotNull(true);
  }

  /**
   * ファイルのフォームに入力されたデータの妥当性検証を行います。 <BR>
   *
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#validate(java.util.ArrayList)
   */
  protected boolean validate(ArrayList msgList) {
    // ファイル追加・チェックイン画面からのアクションの場合、画面項目の検証を行う。
    if (ALEipConstants.MODE_INSERT.equals(getMode())
        || DocumentConstants.MODE_REQUEST_INSERT.equals(getMode())
        || DocumentConstants.MODE_REQAGAIN_INSERT.equals(getMode())
        || ALEipConstants.MODE_CHECKIN.equals(getMode())
        || DocumentConstants.MODE_REQUEST_CHECKIN.equals(getMode())
        || DocumentConstants.MODE_REQAGAIN_CHECKIN.equals(getMode())) {

      // ファイルタイトル
      file_title.validate(msgList);
      // ファイル名
      if (ALEipConstants.MODE_INSERT.equals(getMode())
          || DocumentConstants.MODE_REQUEST_INSERT.equals(getMode())
          || DocumentConstants.MODE_REQAGAIN_INSERT.equals(getMode())) {
        file_name.validate(msgList);
      } else {
        if (fileuploadList != null) {
          if (fileuploadList.size() > 0) {
            file_name.validate(msgList);
          }
        }
      }

      // ファイル追加：障害1 「『ファイル名』を入力してください。」が2回表示される問題の対応
      // ファイル名の未入力はfile_nameでチェックできるため、
      // ファイル追加に関しては、fileidsのチェックは不要
      /*
       * if (fileids != null) { if (fileids[0].equals("")) { if
       * (ALEipConstants.MODE_CHECKIN.equals(getMode())) { msgList.add("『 <span
       * class='em'>チェックインファイル</span> 』を入力してください。"); } else { msgList.add("『
       * <span class='em'>ファイル名</span> 』を入力してください。"); } }
       */

      // メモ
      note.validate(msgList);

      // ファイル名重複チェック
      if (existsFileName()) {
        msgList.add("このファイル名と同じファイルがすでに存在するため、登録できません。ファイル名を変更してください。");
      }

      // チェックイン・チェックイン申請時、必ずチェックインファイルをアップロードさせる。
      if ((ALEipConstants.MODE_CHECKIN.equals(getMode()))
          || DocumentConstants.MODE_REQUEST_CHECKIN.equals(getMode())) {
        if (fileuploadList == null) {
          msgList.add("チェックインファイルを選択してください。");
        }
        // ファイル追加：障害1 「『ファイル名』を入力してください。」が2回表示される問題の対応
        // チェックインに関しては、fileidsもチェックする
        else if (fileids != null && fileids[0].equals("")) {
          msgList.add("チェックインファイルを選択してください。");
        }
      }
      
      // チェックイン再申請時、セレクトボックスが空白の場合のみエラー
      if (DocumentConstants.MODE_REQAGAIN_CHECKIN.equals(getMode())){
        if (fileids != null && fileids[0].equals("")) {
          msgList.add("チェックインファイルを選択してください。");
        }
      }

      // チェックインコメント
      checkinComment.validate(msgList);

      // バージョン
      fileRev.validate(msgList);

      // 公開終了日
      // open_end_date.validate(msgList);

      // 保存終了日
      // save_end_date.validate(msgList);

      if (save_end_date != null && open_end_date != null) {
        if (save_end_date.before(open_end_date)) {
          msgList
              .add("『 <span class='em'>保存終了日</span> 』は『 <span class='em'>公開終了日</span> 』以降の日付を指定してください。");
        }
      }

      Calendar today = Calendar.getInstance();
      Date now = new Date();

      try {
        DateFormat df = new SimpleDateFormat("yyyy/M/d");
        String now_str = df.format(now);
        now = df.parse(now_str);
      } catch (Exception ex) {
        return false;
      }

      today.setTime(now);

      if (open_end_date != null) {
        if (open_end_date.before(today)) {
          msgList
              .add("『 <span class='em'>公開終了日</span> 』は<span class='em'>本日</span>以降の日付を指定してください。");
        }
      }

      if (save_end_date != null) {
        if (save_end_date.before(today)) {
          msgList
              .add("『 <span class='em'>保存終了日</span> 』は<span class='em'>本日</span>以降の日付を指定してください。");
        }
      }
    }

    /** 編集アクセス制限 */
    if (!DocumentUtils.isEditableFolder((int) folder_id.getValue(), rundata))
      msgList.add("このフォルダを編集する権限がありません。");
    
    // 申請時、申請先の検証を行う。
    if (DocumentConstants.MODE_REQUEST_INSERT.equals(getMode())
        || DocumentConstants.MODE_REQAGAIN_INSERT.equals(getMode())
        || DocumentConstants.MODE_REQUEST_CHECKIN.equals(getMode())
        || DocumentConstants.MODE_REQAGAIN_CHECKIN.equals(getMode())
        || DocumentConstants.MODE_REQUEST_CHECKOUT.equals(getMode())
        || DocumentConstants.MODE_REQUEST_CHECKOUT_CANCEL.equals(getMode())
        || DocumentConstants.MODE_REQUEST_DELETE.equals(getMode())
    ){
      // 申請先の空チェック
      if (workflowMemberList == null || workflowMemberList.size() <= 0) {
        msgList.add("『 <span class='em'>申請先</span> 』を指定してください。");
      } else if(workflowMemberList.size() == 1) {
        // 申請先が自分だけの場合、NGにする。
        int uid = ALEipUtils.getUserId(rundata);
        int workflow_uid = (int)(((ALEipUser)(workflowMemberList.get(0))).getUserId().getValue());
        if (uid == workflow_uid){
          msgList.add("自分以外のユーザーを1人以上申請先に含む必要があります。");
        }
      }      
    }

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

  private boolean existsFileName() {
    String fname = file_name.getValue();
    if (fname == null || "".equals(fname))
      return false;

    try {
      SelectQuery query = new SelectQuery(ImwTDocumentFile.class);
      query.addCustomDbAttribute(ImwTDocumentFile.FILE_NAME_COLUMN);

      // 同一フォルダのファイルに限定
      Expression exp1 = ExpressionFactory.matchDbExp(
          ImwTDocumentFolder.FOLDER_ID_PK_COLUMN, Integer
              .valueOf((int) folder_id.getValue()));
      query.setQualifier(exp1);
      // 現在編集中のファイルと同じ文書IDのファイルを除外
      if (this.docId != null) {
        Expression exp2 = ExpressionFactory.noMatchExp(
            ImwTDocumentFile.DOC_ID_PROPERTY, this.docId);
        query.andQualifier(exp2);
      }
      // 過去のファイルを除外
      Expression exp3 = ExpressionFactory.noMatchExp(
          ImwTDocumentFile.STATUS_PROPERTY, "2");
      query.andQualifier(exp3);

      List list = dataContext.performQuery(query);
      if (list != null && list.size() > 0) {
        DataRow dataRow = null;
        int size = list.size();
        for (int i = 0; i < size; i++) {
          dataRow = (DataRow) list.get(i);
          if (fname.equals((String) ALEipUtils.getObjFromDataRow(dataRow,
              ImwTDocumentFile.FILE_NAME_COLUMN))) {
            return true;
          }
        }
      }
    } catch (Exception e) {
      return true;
    }

    return false;
  }

  /**
   * ファイルをデータベースから読み出します。 <BR>
   *
   * @param rundata
   * @param context
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#loadFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context)
   */
  protected boolean loadFormData(RunData rundata, Context context,
      ArrayList msgList) {
    try {
      // オブジェクトモデルを取得
      ImwTDocumentFile file = DocumentUtils.getImwTDocumentFile(rundata,
          context);
      if (file == null)
        return false;

      file_id = (int) file.getFileId();

      // 親フォルダ
      folder_id.setValue(file.getFolderId().intValue());
      // ファイルタイトル
      file_title.setValue(file.getFileTitle());
      // ファイル名
      file_name.setValue(file.getFileName());
      // ファイルサイズ
      file_size.setValue(file.getFileSize().longValue());
      // メモ
      note.setValue(file.getNote());
      // フォルダ名
      folderName = Integer.toString(file.getFolderId());

      // 公開終了日
      if (file.getOpenEndDate() != null) {
        open_end_date = Calendar.getInstance();
        open_end_date.setTime(file.getOpenEndDate());
      }

      // 保存終了日
      if (file.getSaveEndDate() != null) {
        save_end_date = Calendar.getInstance();
        save_end_date.setTime(file.getSaveEndDate());
      }

      // チェックインコメント
      checkinComment.setValue(file.getCheckinComment());

      // 初期表示用　閲覧権限メンバーグループリスト
      initReadGroupList = new ArrayList();

      // 初期表示用　閲覧権限メンバーユーザーリスト
      initReadUserList = new ArrayList();

      // 初期表示用　編集権限メンバーグループリスト
      initEditGroupList = new ArrayList();

      // 初期表示用　編集権限メンバーユーザーリスト
      initEditUserList = new ArrayList();

      is_member_read = true;
      is_member_edit = true;

      // 閲覧メンバーリストを取得
      getMemberFromMap(initReadGroupList, initReadUserList, file.getDocId(),
          Integer.valueOf(0));

      // 編集メンバーリストを取得
      getMemberFromMap(initEditGroupList, initEditUserList, file.getDocId(),
          Integer.valueOf(1));

      // 関連文書を取得
      getRelationFiles(initRelationList, file.getDocId());

      // ワークフロー申請先 ・申請経路（再申請時のみセット） 画面表示時はDBを見て判断
      if (this.isDocReqAgain) {
        EipTWorkflowRequest request = DocumentUtils
            .getEipTWorkflowRequestByDocId(file.getDocId());

        // 申請経路ID
        is_saved_route = false;
        route_id.setValue(null);
        route.setValue(null);
        if (request.getEipTWorkflowRoute() != null) {
          is_saved_route = true;
          route_id.setValue(request.getEipTWorkflowRoute().getRouteId()
              .longValue());
          route.setValue(request.getEipTWorkflowRoute().getRoute());
        }

        // 申請先
        workflowMemberList.clear();
        List maps = WorkflowUtils.getEipTWorkflowRequestMap(request);
        EipTWorkflowRequestMap map = null;
        int size = maps.size();
        for (int i = 0; i < size; i++) {
          map = (EipTWorkflowRequestMap) maps.get(i);
          int user_id = map.getUserId().intValue();
          if (!WorkflowUtils.DB_STATUS_REQUEST.equals(map.getStatus())) {
            workflowMemberList.add(ALEipUtils.getALEipUser(user_id));
          }
        }
      }

    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  /**
   * IMW_T_DOCUMENT_RELATION_MAP から関連文書を抽出します
   * 
   */
  protected boolean getRelationFiles(List relationList, Integer docId) {
    try {
      // 変数の宣言
      SelectQuery query;
      Expression exp, exp2;
      int requestStatus = 0;
      
      relationList.clear();
      
      //　申請状態
      if(getRequestMode()==2){
        requestStatus = 1;
      } else {
        requestStatus = 0;
      }

      // グループのリストを取得
      query = new SelectQuery(ImwTDocumentRelationMap.class);
      exp = ExpressionFactory.matchExp(ImwTDocumentRelationMap.DOC_ID_PROPERTY,
          docId);
      query.setQualifier(exp);
      exp2 = ExpressionFactory.matchExp(ImwTDocumentRelationMap.REQUEST_STATUS_PROPERTY,
          requestStatus);
      query.andQualifier(exp2);
      List list = dataContext.performQuery(query);
      int size = list.size();
      if (list != null && size > 0) {
        for (int i = 0; i < size; i++) {
          relationList.add((ImwTDocumentRelationMap) list.get(i));
        }
      }

      return true;
    } catch (Exception ex) {
      return false;
    }
  }

  /**
   * IMW_T_DOCUMENT_FILE_MAP から権限を持つグループリストとユーザリストを抽出します
   * 
   */
  protected boolean getMemberFromMap(ArrayList groupList, ArrayList userList,
      Integer docId, Integer editable) {
    try {

      // 変数の宣言
      SelectQuery query;
      Expression exp, exp2, exp3;
      
      int requestStatus = 0;
      
      // 再申請時は申請時のデータを取得
      if (this.isDocReqAgain){
        requestStatus = 1;
      } else {
        requestStatus = 0;
      }
      
      // グループのリストを取得
      query = new SelectQuery(ImwTDocumentFileMap.class);
      exp = ExpressionFactory.matchExp(ImwTDocumentFileMap.DOC_ID_PROPERTY,
          docId);
      exp2 = ExpressionFactory.matchExp(ImwTDocumentFileMap.EDITABLE_PROPERTY,
          editable);
      exp3 = ExpressionFactory.matchExp(ImwTDocumentFileMap.REQUEST_STATUS_PROPERTY,
          requestStatus);
      query.setQualifier(exp);
      query.andQualifier(exp2);
      query.andQualifier(exp3);
      List glist = dataContext.performQuery(query);

      List group = new ArrayList();
      int gsize = glist.size();
      for (int i = 0; i < gsize; i++) {
        ImwTDocumentFileMap map = (ImwTDocumentFileMap) glist.get(i);
        Integer gid = map.getGroupId();
        if (gid != null) {
          //全ユーザーが権限を持つ場合
          if (gid.intValue() == -1) {
            if (editable.intValue() == 1) {
              is_member_edit = false;
              break;
            } else {
              is_member_read = false;
              break;
            }
          }
          group.add(map.getGroupId());
        }
      }
      query = new SelectQuery(TurbineGroup.class);
      exp = ExpressionFactory.inDbExp(TurbineGroup.GROUP_ID_PK_COLUMN, group);
      query.setQualifier(exp);
      groupList.addAll(DocumentUtils.getGroupFromSelectQuery(query));

      // メンバーのリストを取得
      query = new SelectQuery(ImwTDocumentFileMap.class);
      exp = ExpressionFactory.matchExp(ImwTDocumentFileMap.DOC_ID_PROPERTY,
          docId);
      exp2 = ExpressionFactory.matchExp(ImwTDocumentFileMap.EDITABLE_PROPERTY,
          editable);
      exp3 = ExpressionFactory.matchExp(ImwTDocumentFileMap.REQUEST_STATUS_PROPERTY,
          requestStatus);
      query.setQualifier(exp);
      query.andQualifier(exp2);
      query.andQualifier(exp3);
      List list = dataContext.performQuery(query);

      List users = new ArrayList();
      int usize = list.size();
      for (int i = 0; i < usize; i++) {
        ImwTDocumentFileMap map = (ImwTDocumentFileMap) list.get(i);
        users.add(map.getUserId());
      }
      query = new SelectQuery(TurbineUser.class);
      exp = ExpressionFactory.inDbExp(TurbineUser.USER_ID_PK_COLUMN, users);
      query.setQualifier(exp);
      userList.addAll(DocumentUtils.getUsersFromSelectQuery(query));

      return true;
    } catch (Exception ex) {
      return false;
    }
  }

  /**
   * ファイルをデータベースとファイルシステムから削除します。 <BR>
   *
   * @param rundata
   * @param context
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#deleteFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context)
   */
  protected boolean deleteFormData(RunData rundata, Context context,
      ArrayList msgList) {
    try {
      // オブジェクトモデルを取得
      ImwTDocumentFile file = DocumentUtils.getImwTDocumentFile(rundata,
          context);
      if (file == null)
        return false;

      // ファイルのパス
      String local_file_pass = file.getFilePath();

      // entityIdの取得
      int entityId = file.getFileId();
      // todo名の取得
      String fileName = file.getFileTitle();

      // ファイルを削除
      dataContext.deleteObject(file);
      dataContext.commitChanges();

      // イベントログに保存
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(entityId,
          ALEventlogConstants.PORTLET_TYPE_DOCUMENT_FILE, fileName);

      if (local_file_pass != null && !"".equals(local_file_pass)) {
        // ローカルファイルに保存されているファイルを削除する．
        File local_file = null;
        local_file = new File(DocumentUtils.getSaveDirPath(org_id)
            + local_file_pass);
        if (local_file.exists()) {
          local_file.delete();
        }
      }

    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  /**
   * ファイルをデータベースとファイルシステムから削除します
   * @param action
   * @param rundata
   * @param context
   * @return TRUE 成功 FALSE 失敗
   */
  public boolean doDelete(ALAction action, RunData rundata, Context context) {

    try {

      ArrayList msgList = new ArrayList();
      
      //セキュリティチェック
      if (!doCheckSecurity(rundata, context)) {
        return false;
      }

      init(action, rundata, context);
      //権限チェック
      doCheckAclPermission(rundata, context,
          ALAccessControlConstants.VALUE_ACL_DELETE);

      String org_id = DatabaseOrmService.getInstance().getOrgId(rundata);
      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      ImwTDocumentFile file = DocumentUtils.getImwTDocumentFile(rundata,
          context);
      
      if (file == null){
        msgList.add("文書が存在しません。");
        action.addErrorMessages(msgList);
        action.putData(rundata, context);
        return false;
      }
      
      if(DocumentUtils.isDocRequesting(file)){
        //　申請中の場合
        msgList.add("申請中のファイルは削除できません。");
        action.addErrorMessages(msgList);
        action.putData(rundata, context);
        return false;
      }
      
      List relation_file_path = DocumentUtils.getImwTDocumentRelationMap(file
          .getDocId()); 

      // ファイルパスの取得
      List local_file_path = LibDocumentUtils.getDocFilePathList(file.getDocId());

      //　ファイルIDの取得
      int entityId = file.getFileId();
      // ファイルタイトルの取得
      String fileName = file.getFileTitle();

      //文書ファイルマップIDの取得
      String relFileId = file.getDocId().toString();

      //文書ファイル
      Expression expressionFile = ExpressionFactory.matchExp(
          ImwTDocumentFile.DOC_ID_PROPERTY, relFileId);
      //文書ファイルマップ
      Expression expressionFileMap = ExpressionFactory.matchExp(
          ImwTDocumentFileMap.DOC_ID_PROPERTY, relFileId);
      //文書ファイル関連マップ
      Expression expressionRelationMap = ExpressionFactory.matchExp(
          ImwTDocumentRelationMap.DOC_ID_PROPERTY, relFileId);

      SelectQuery queryFile = new SelectQuery(ImwTDocumentFile.class);
      SelectQuery queryFileMap = new SelectQuery(ImwTDocumentFileMap.class);
      SelectQuery queryRelationMap = new SelectQuery(
          ImwTDocumentRelationMap.class);

      queryFile.setQualifier(expressionFile);
      queryFileMap.setQualifier(expressionFileMap);
      queryRelationMap.setQualifier(expressionRelationMap);

      List listFile = dataContext.performQuery(queryFile);
      List listFileMap = dataContext.performQuery(queryFileMap);
      List listFileRelationMap = dataContext.performQuery(queryRelationMap);

      //文書ファイルマップ
      dataContext.deleteObjects(listFileMap);
      //関連文書ファイルマップ
      dataContext.deleteObjects(listFileRelationMap);
      //文書ファイル
      dataContext.deleteObjects(listFile);

      dataContext.commitChanges();

      // イベントログに保存
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(entityId,
          ALEventlogConstants.PORTLET_TYPE_DOCUMENT_FILE, fileName);

      if (local_file_path != null && local_file_path.size() > 0) {
        for (int i = 0; i < local_file_path.size(); i++) {
          // ローカルファイルに保存されているファイルを削除する．
          File local_file = null;
          local_file = new File(DocumentUtils.getSaveDirPath(org_id)
              + local_file_path.get(i).toString());
          if (local_file.exists()) {
            local_file.delete();
          }
        }
      }    
      
      if (relation_file_path != null && relation_file_path.size() > 0) {
        for (int i = 0; i < relation_file_path.size(); i++) {
          // ローカルファイルに保存されている関連文書を削除する．
          File local_file = null;
          local_file = new File(DocumentUtils.getSaveDirPath(org_id)
              + relation_file_path.get(i).toString());
          if (local_file.exists()) {
            local_file.delete();
          }
        }
      }

    } catch (ALPermissionException e) {
      ALEipUtils.redirectPermissionError(rundata);
      return false;
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  /**
   * 申請を破棄します
   * @param action
   * @param rundata
   * @param context
   * @return TRUE 成功 FALSE 失敗
   */
  public boolean doRequestCancel(ALAction action, RunData rundata,
      Context context) {

    try {

      //セキュリティチェック
      if (!doCheckSecurity(rundata, context)) {
        return false;
      }

      init(action, rundata, context);
      //権限チェック
      //doCheckAclPermission(rundata, context,
      //    ALAccessControlConstants.VALUE_ACL_DELETE);
      
      // ログインユーザが申請者とシステム管理者以外なら失敗
      ArrayList msgList = new ArrayList();
      int current_user_id = ALEipUtils.getUserId(rundata);
      ImwTDocumentRequestMap reqMap = DocumentUtils
          .getImwTDocumentRequestMapByDocId(this.docId);
      if (!this.isDocAdmin && 
          (reqMap == null || reqMap.getRequestUserId() == null
           || current_user_id != reqMap.getRequestUserId().intValue())) {
        msgList.add("ログインユーザーが申請者または文書管理システム管理者ではありません。");
        action.addErrorMessages(msgList);
        action.putData(rundata, context);
        return false;
      }
     
      String org_id = DatabaseOrmService.getInstance().getOrgId(rundata);
      ImwTDocumentFile file = DocumentUtils.getImwTDocumentFile(rundata,
          context);
      ArrayList relation_file_path = LibDocumentUtils.getRelationFilePaths(file
          .getDocId(), Integer.valueOf(1));

      if (file == null)
        return false;

      // 申請オブジェクト
      EipTWorkflowRequest request = DocumentUtils
          .getEipTWorkflowRequestByDocId(file.getDocId());
      String catname = request.getEipTWorkflowCategory().getCategoryName();
      // 申請削除処理
      if (!DocumentUtils.deleteRequest(dataContext, request))
        return false;

      // 文書削除処理
      if (!LibDocumentUtils.deleteDocument(dataContext, file, Integer.valueOf(1)))
        return false;

      // DBに反映
      dataContext.commitChanges();

      // 申請削除後処理
      DocumentUtils.deleteRequestEnd(request, catname);

      // 文書削除後処理
      //DocumentUtils.deleteDocumentEnd(file, org_id, relation_file_path);
      LibDocumentUtils.deleteDocumentEnd(file, org_id, relation_file_path);

      //}catch (ALPermissionException e) {
      //  ALEipUtils.redirectPermissionError(rundata);
      //  return false;
    } catch (Exception ex) {
      dataContext.rollbackChanges();
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }
  
  /**
   * ファイル追加申請もしくはファイル追加再申請を行います。
   * 
   * @param action
   * @param rundata
   * @param context
   * @return TRUE 成功 FALSE 失敗
   */
  public boolean doRequestInsert(ALAction action, RunData rundata,
      Context context) {
    try {

      if (!doCheckSecurity(rundata, context)) {
        return false;
      }

      init(action, rundata, context);

      doCheckAclPermission(rundata, context,
          ALAccessControlConstants.VALUE_ACL_INSERT);

      //action.setMode(action.getMode());

      setMode(action.getMode());

      ArrayList msgList = new ArrayList();
      setValidator();
      boolean res = (setFormData(rundata, context, msgList)
          && validate(msgList) && insertFormData(rundata, context, msgList));

      if (!res) {
        action.setMode(ALEipConstants.MODE_EDIT_FORM);
        setMode(action.getMode());
      }
      action.setResultData(this);
      action.addErrorMessages(msgList);
      action.putData(rundata, context);

      return res;
    } catch (ALPermissionException e) {
      ALEipUtils.redirectPermissionError(rundata);
      return false;
    } catch (ALPageNotFoundException e) {
      ALEipUtils.redirectPageNotFound(rundata);
      return false;
    } catch (ALDBErrorException e) {
      ALEipUtils.redirectDBError(rundata);
      return false;
    }
  }

  /**
   * ファイル追加もしくは追加申請もしくは追加再申請を行います。<BR>
   * ファイルをデータベースとファイルシステムに格納します。 <BR>
   *
   * @param rundata
   * @param context
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#insertFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  protected boolean insertFormData(RunData rundata, Context context,
      ArrayList msgList) {
    boolean res = true;
    String localFilePath = null;

    try {

      ImwTDocumentFile file = null;

        // 追加再申請の場合
      if(DocumentConstants.MODE_REQAGAIN_INSERT.equals(getMode())) {
        file = DocumentUtils.getImwTDocumentFile(rundata, context);
        if (file == null)
          return false;

        // ログインユーザが申請者以外なら失敗
        int current_user_id = ALEipUtils.getUserId(rundata);
        ImwTDocumentRequestMap reqMap = DocumentUtils
            .getImwTDocumentRequestMapByDocId(file.getDocId());
        if (reqMap == null || reqMap.getRequestUserId() == null
            || current_user_id != reqMap.getRequestUserId().intValue()) {
          msgList.add("ログインユーザーが申請者ではありません。");
          return false;
        }

        // ファイルを新規追加した場合、既存のファイルパスを取得
        if (fileids != null && !"I".equals(fileids[0])) {
          localFilePath = file.getFilePath();
        }

        // ファイルマップテーブルの削除
        if(!LibDocumentUtils
            .deleteFileMap(dataContext, file.getDocId(), Integer.valueOf(1))){
          dataContext.rollbackChanges();
          return false;
        }
      } else {
        // ファイル追加か追加申請の場合
        // 新規オブジェクトモデル作成
        file = (ImwTDocumentFile) dataContext
            .createAndRegisterNewObject(ImwTDocumentFile.class);
      }

      // 共通ファイル追加処理
      if (!commonInsert(rundata, context, msgList, file))
        return false;

      //　ファイル追加の場合
      if (ALEipConstants.MODE_INSERT.equals(getMode())) {
        // DBに反映
        dataContext.commitChanges();
      } else {      
        // 申請もしくは再申請の場合

        // ワークフロー依頼オブジェクトの作成
        EipTWorkflowRequest request = (EipTWorkflowRequest) dataContext
            .createAndRegisterNewObject(EipTWorkflowRequest.class);

        String[] relationids = rundata.getParameters().getStrings("relations");

        // 申請内容
        String note = DocumentUtils.getNewFileInfo(file, is_member_read,
            is_member_edit, memberReadGroupList, memberReadUserList,
            memberEditGroupList, memberEditUserList, relationids,
            relationuploadList);
        // 申請処理
        if (!DocumentUtils.insertRequest(rundata, dataContext, file, request,
            getMode(), note, workflowMemberList, is_saved_route, route_id
                .getValue()))
          return false;

        // DB反映
        dataContext.commitChanges();

        // 申請後処理（イベントログの追加、新着情報の追加、次申請者へのメール送信）
        DocumentUtils.insertRequestEnd(rundata, dataContext, file, request,
            workflowMemberList);

        // 追加再申請時
        if (DocumentConstants.MODE_REQAGAIN_INSERT.equals(getMode())) {
          if (localFilePath != null && !"".equals(localFilePath)) {
            // ローカルファイルに保存されているファイルを削除する．
            File local_file = null;
            local_file = new File(DocumentUtils.getSaveDirPath(org_id)
                + localFilePath);
            if (local_file.exists()) {
              local_file.delete();
            }
          }
        }
      }

      // イベントログに保存
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(
          file.getFileId(), ALEventlogConstants.PORTLET_TYPE_DOCUMENT_FILE,
          file_title.getValue());

      int uid = ALEipUtils.getUserId(rundata);
      File folder_tmp = FileuploadUtils.getFolder(org_id, uid, folderName);
      // 添付ファイル保存先のフォルダを削除
      FileuploadUtils.deleteFolder(folder_tmp);

    } catch (Exception ex) {
      dataContext.rollbackChanges();
      logger.error("Exception", ex);
      return false;
    }
    return res;
  }

  protected boolean commonInsert(RunData rundata, Context context,
      ArrayList msgList, ImwTDocumentFile file) {
    try {
      int uid = ALEipUtils.getUserId(rundata);

      // ファイルが新規追加された場合
      if (fileids != null && !"I".equals(fileids[0])) {
        FileuploadLiteBean filebean = (FileuploadLiteBean) fileuploadList
            .get(0);
        // ファイルの移動先
        String filename = FileuploadUtils.getNewFileName(DocumentUtils
            .getSaveDirPath(org_id));

        // ファイルの移動先
        File destFile = new File(DocumentUtils
            .getAbsolutePath(org_id, filename));

        // 一時保存の添付ファイル
        File srcFile = FileuploadUtils.getAbsolutePath(org_id, uid, folderName,
            filebean.getFileId());

        // ファイルの移動
        FileuploadUtils.copyFile(srcFile, destFile);

        double fileSize = Math.ceil(destFile.length() / 1024.0);

        // ファイルサイズ
        file.setFileSize(Long.valueOf((long) fileSize));
        // ファイルパス
        file.setFilePath(DocumentUtils.getRelativePath(filename));
        // ファイル名
        file.setFileName(file_name.getValue());

      }

      // 関連文書ファイルの移動

      ImwTDocumentFolder folder = (ImwTDocumentFolder) DataObjectUtils
          .objectForPK(dataContext, ImwTDocumentFolder.class, Integer
              .valueOf((int) folder_id.getValue()));

      // 親フォルダ
      file.setImwTDocumentFolder(folder);
      // ファイルタイトル
      file.setFileTitle(file_title.getValue());

      // ファイル
      // file.setFile(fileData);
      // メモ
      file.setNote(note.getValue());
      // 作成者
      file.setCreateUserId(Integer.valueOf(uid));
      // 更新者
      file.setUpdateUserId(Integer.valueOf(uid));
      // 作成日
      file.setCreateDate(Calendar.getInstance().getTime());
      // 更新日
      file.setUpdateDate(Calendar.getInstance().getTime());

      // チェックアウト者IDはダミーの-1を入れる
      file.setCheckoutUserId(Integer.valueOf(-1));

      // リビジョン
      if ("1.0".equals(fileRev.getValue())) {
        file.setFileRevMj(1);
        file.setFileRevMn(0);
      } else {
        file.setFileRevMj(0);
        file.setFileRevMn(1);
      }

      // 公開終了日
      if (open_end_date != null) {
        file.setOpenEndDate(open_end_date.getTime());
      }

      // 保存終了日
      if (save_end_date != null) {
        file.setSaveEndDate(save_end_date.getTime());
      }

      //　文書ID
      Integer docId;
      //Integer docId = DocumentUtils.getMaxDocId() + 1;
      if (!DocumentConstants.MODE_REQAGAIN_INSERT.equals(getMode())) {
        docId = DocumentUtils.getNextDocId();
      } else {
        docId = file.getDocId();
      }

      if (docId == null) {
        dataContext.rollbackChanges();
        return false;
      }

      file.setDocId(docId);

      // 申請状態
      Integer requestStatus = null;
      if (ALEipConstants.MODE_INSERT.equals(getMode())) {
        requestStatus = Integer.valueOf(0);
      } else {
        requestStatus = Integer.valueOf(1);
      }

      // 関連文書
      if (!DocumentUtils.insertRelationFiles(rundata, context, dataContext,
          docId, requestStatus, relationuploadList, folderName, msgList)) {
        dataContext.rollbackChanges();
        return false;
      }

      // チェックインコメント
      file.setCheckinComment(checkinComment.getValue());

      //System.out.println("checkval = " + checkinComment.getValue());

      // アクセス権の削除
      SelectQuery query = new SelectQuery(ImwTDocumentFileMap.class);
      Expression exp = ExpressionFactory.matchExp(
          ImwTDocumentFile.DOC_ID_PROPERTY, docId);
      query.setQualifier(exp);
      List oldMapList = dataContext.performQuery(query);
      dataContext.deleteObjects(oldMapList);

      // 閲覧権限
      if (is_member_read) {
        insertFileMap(memberReadGroupList, memberReadUserList, docId, Integer
            .valueOf(0), requestStatus);
      } else {
        insertFileMapAllUser(docId, Integer.valueOf(0), requestStatus);
      }

      // 編集権限
      if (is_member_edit) {
        insertFileMap(memberEditGroupList, memberEditUserList, docId, Integer
            .valueOf(1), requestStatus);
      } else {
        insertFileMapAllUser(docId, Integer.valueOf(1), requestStatus);
      }
      // チェックアウトID
      // file.setCheckoutUserId(Integer.valueOf(uid));

      // ステータス
      if (ALEipConstants.MODE_INSERT.equals(getMode())) {
        file.setStatus("0");
      } else {
        file.setStatus("3");
      }
    } catch (Exception ex) {
      dataContext.rollbackChanges();
      logger.error("Exception", ex);
      return false;
    }

    return true;
  }

  /**
   * グループリストとユーザリストをIMW_T_DOCUMENT_FILE_MAPテーブルに挿入します。 <BR>
   *
   */
  protected boolean insertFileMap(ArrayList groupList, ArrayList userList,
      Integer docId, Integer editable, Integer requestStatus) {
    try {
      //アクセス権限　ユーザ
      for (int i = 0; i < userList.size(); i++) {
        ImwTDocumentFileMap map = (ImwTDocumentFileMap) dataContext
            .createAndRegisterNewObject(ImwTDocumentFileMap.class);
        ALEipUser user = (ALEipUser) userList.get(i);
        int user_id = (int) user.getUserId().getValue();

        //map.setImwTDocumentFile(file);
        map.setUserId(Integer.valueOf(user_id));
        map.setDocId(docId);
        map.setEditable(editable);
        map.setRequestStatus(requestStatus);
      }

      //アクセス権限　グループ
      for (int i = 0; i < groupList.size(); i++) {
        ImwTDocumentFileMap map = (ImwTDocumentFileMap) dataContext
            .createAndRegisterNewObject(ImwTDocumentFileMap.class);
        TurbineGroup group = (TurbineGroup) groupList.get(i);
        String group_id = (String) group.getId();

        //map.setImwTDocumentFile(file);
        map.setGroupId(Integer.valueOf(group_id));
        map.setDocId(docId);
        map.setEditable(editable);
        map.setRequestStatus(requestStatus);
      }

      return true;
    } catch (Exception ex) {
      dataContext.rollbackChanges();
      logger.error("Exception", ex);
      return false;
    }
  }

  /**
   * 全てのユーザを示す値をIMW_T_DOCUMENT_FILE_MAPテーブルに挿入します。 <BR>
   *
   */
  protected boolean insertFileMapAllUser(Integer docId, Integer editable,
      Integer requestStatus) {
    try {
      ImwTDocumentFileMap map = (ImwTDocumentFileMap) dataContext
          .createAndRegisterNewObject(ImwTDocumentFileMap.class);
      map.setGroupId(Integer.valueOf(-1));
      map.setDocId(docId);
      map.setEditable(editable);
      map.setRequestStatus(requestStatus);
      return true;
    } catch (Exception ex) {
      dataContext.rollbackChanges();
      logger.error("Exception", ex);
      return false;
    }
  }

  /**
   * データベースとファイルシステムに格納されているファイルを更新します。 <BR>
   *
   * @param rundata
   * @param context
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#updateFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  protected boolean updateFormData(RunData rundata, Context context,
      ArrayList msgList) {
    try {
      int uid = ALEipUtils.getUserId(rundata);

      // オブジェクトモデルを取得
      ImwTDocumentFile file = DocumentUtils.getImwTDocumentFile(rundata,
          context);
      if (file == null)
        return false;

      // アップロードしたファイルは存在するか
      boolean is_upload = true;
      if (fileuploadList == null) {
        is_upload = false;
      }
      if (is_upload) {
        // アップロードが確認できた場合
        FileuploadLiteBean filebean = (FileuploadLiteBean) fileuploadList
            .get(0);
        String filename = FileuploadUtils.getNewFileName(DocumentUtils
            .getSaveDirPath(org_id));
        // ファイルの移動先
        File destFile = new File(DocumentUtils
            .getAbsolutePath(org_id, filename));

        // 一時保存の添付ファイル
        File srcFile = FileuploadUtils.getAbsolutePath(org_id, uid, folderName,
            filebean.getFileId());

        // ファイルの移動
        FileuploadUtils.copyFile(srcFile, destFile);

        // ファイル名
        file.setFileName(file_name.getValue());

        // ファイルサイズ
        double fileSize = Math.ceil(destFile.length() / 1024.0);
        file.setFileSize(Long.valueOf((long) fileSize));

        // ファイルパス
        file.setFilePath(DocumentUtils.getRelativePath(filename));
        // 作成者
        file.setCreateUserId(Integer.valueOf(uid));
        // 作成日
        file.setCreateDate(Calendar.getInstance().getTime());

        // リビジョン
        file.setFileRevMj(1);
        file.setFileRevMn(0);

        // ステータス
        file.setStatus("0");
      }

      // 親フォルダ
      ImwTDocumentFolder folder = (ImwTDocumentFolder) DataObjectUtils
          .objectForPK(dataContext, ImwTDocumentFolder.class, Integer
              .valueOf((int) folder_id.getValue()));
      file.setImwTDocumentFolder(folder);

      // ファイルタイトル
      file.setFileTitle(file_title.getValue());
      // メモ
      file.setNote(note.getValue());
      // 更新者
      file.setUpdateUserId(Integer.valueOf(uid));
      // 更新日
      file.setUpdateDate(Calendar.getInstance().getTime());
      // フォルダを更新
      dataContext.commitChanges();

      // イベントログに保存
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(
          file.getFileId(), ALEventlogConstants.PORTLET_TYPE_DOCUMENT_FILE,
          file_title.getValue());

    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  /**
   * ファイルチェックアウトもしくはチェックアウト申請を行います。
   * @param action 
   * @param rundata
   * @param context
   * @return　TRUE 成功 FALSE 失敗
   */
  public boolean doCheckOut(ALAction action, RunData rundata, Context context) {
    try {
      init(action, rundata, context);

      doCheckAclPermission(rundata, context,
          ALAccessControlConstants.VALUE_ACL_UPDATE);

      setMode(action.getMode());
      
      ArrayList msgList = new ArrayList();
      
      //ユーザーID
      int uid = ALEipUtils.getUserId(rundata);

      // オブジェクトモデルを取得
      ImwTDocumentFile file = DocumentUtils.getImwTDocumentFile(rundata,
          context);
      
      if (file==null){
        msgList.add("文書が存在しません。");
        action.addErrorMessages(msgList);
        action.putData(rundata, context);
        return false;
      }

      // 排他チェック（Statusの取得）
      //　既にfileにファイル情報が取得されているが、排他のためにSELECT　FOR　UPDATEを行う。
      StringBuffer statement = new StringBuffer();
      statement.append(" SELECT ");
      statement.append("  STATUS");
      statement.append(" FROM IMW_T_DOCUMENT_FILE");
      statement.append("  WHERE FILE_ID = " + file.getFileId());
      statement.append(" FOR UPDATE");
      String query = statement.toString();

      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      SQLTemplate rawSelect = new SQLTemplate(ImwTDocumentFile.class, query,
          true);
      rawSelect.setFetchingDataRows(true);
      List list = dataContext.performQuery(rawSelect);
      DataRow dataRow;
      int recordNum = list.size();
      String strStatus = "";
      for (int i = 0; i < recordNum; i++) {
        dataRow = (DataRow) list.get(i);
        strStatus = ALEipUtils.getObjFromDataRow(dataRow, "STATUS").toString();
      }
      
      //ステータスの判断、
      if (!strStatus.equals("0")) {
        /**チェックアウトの場合、メッセージを表示する*/
        msgList.add("既にチェックアウトされています。");
        action.addErrorMessages(msgList);
        action.putData(rundata, context);
        return false;
      } else {
        // チェックアウトされていない場合
        // チェックアウト処理
        if (ALEipConstants.MODE_CHECKOUT.equals(getMode())) {
          
          if(DocumentUtils.isDocRequesting(file)){
            //　申請中の場合
            msgList.add("申請中のファイルはチェックアウトできません。");
            action.addErrorMessages(msgList);
            action.putData(rundata, context);
            return false;
          }
          
          // ステータス
          file.setStatus("1");
          // チェックアウト者
          file.setCheckoutUserId(Integer.valueOf(uid));
          // チェックアウト日
          file.setCheckoutDate(Calendar.getInstance().getTime());
          // 更新実行
          dataContext.commitChanges();
          
          return true;
        } else if (DocumentConstants.MODE_REQUEST_CHECKOUT.equals(getMode())) {
          // チェックアウト申請
          setValidator();
          boolean res = (setFormData(rundata, context, msgList)
              && validate(msgList) && requestFormData(rundata, context, msgList));
          if (!res) {
            action.setMode(ALEipConstants.MODE_NEW_FORM);
            //mode = action.getMode();
          }
          action.setResultData(this);
          action.addErrorMessages(msgList);
          action.putData(rundata, context);
          return res;        
        }
      }
    } catch (ALPermissionException e) {
      ALEipUtils.redirectPermissionError(rundata);
      return false;
    } catch (Exception ex) {
      //エラー
      dataContext.rollbackChanges();
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  public boolean requestFormData(RunData rundata, Context context,
      ArrayList msgList){
    try {
      // オブジェクトモデルを取得
      ImwTDocumentFile file = DocumentUtils.getImwTDocumentFile(rundata,
          context);
      
      if (file==null){
        return false;
      }
      
      //　申請中チェック
      if(DocumentUtils.isDocRequesting(file)){
        msgList.add("このファイルは既に申請されています。");
        return false;
      }
      
      // ワークフロー依頼オブジェクトの作成
      EipTWorkflowRequest request = (EipTWorkflowRequest) dataContext
          .createAndRegisterNewObject(EipTWorkflowRequest.class);
      
      // 申請内容
      String note = DocumentUtils.getOldFileInfo(file);

      // 申請処理
      if (!DocumentUtils.insertRequest(rundata, dataContext, file, request,
          getMode(), note, workflowMemberList, is_saved_route, route_id
              .getValue())) {
        return false;
      }
      
      // DB反映
      dataContext.commitChanges();
      
      // 申請後処理（イベントログの追加、新着情報の追加、次申請者へのメール送信）
      DocumentUtils.insertRequestEnd(rundata, dataContext, file, request,
          workflowMemberList);
      return true;
    } catch (Exception ex) {
      dataContext.rollbackChanges();
      logger.error("Exception", ex);
      return false;
    }
  }
  
  /**
   * チェックアウトをキャンセルします。
   * 
   * @param action
   * @param rundata
   * @param context
   * @return TRUE 成功 FALSE 失敗
   */
  public boolean doCheckoutCancel(ALAction action, RunData rundata,
      Context context) {
    try {
  
      if (!doCheckSecurity(rundata, context)) {
        return false;
      }
  
      init(action, rundata, context);
  
      doCheckAclPermission(rundata, context,
          ALAccessControlConstants.VALUE_ACL_UPDATE);
  
      action.setMode("checkoutCancel");
  
      setMode(action.getMode());
  
      ArrayList msgList = new ArrayList();
      setValidator();
      //boolean res = (setFormData(rundata, context, msgList)
      //    && validate(msgList) && checkoutCancelFormData(rundata, context, msgList));
      boolean res = checkoutCancelFormData(rundata, context, msgList);
      if (!res) {
        action.setMode(ALEipConstants.MODE_EDIT_FORM);
        setMode(action.getMode());
      }
      action.setResultData(this);
      action.addErrorMessages(msgList);
      action.putData(rundata, context);
  
      return res;
    } catch (ALPermissionException e) {
      ALEipUtils.redirectPermissionError(rundata);
      return false;
    } catch (ALPageNotFoundException e) {
      ALEipUtils.redirectPageNotFound(rundata);
      return false;
    } catch (ALDBErrorException e) {
      ALEipUtils.redirectDBError(rundata);
      return false;
    }
  }

  /**
   * チェックアウト取消申請します。
   * 
   * @param action
   * @param rundata
   * @param context
   * @return TRUE 成功 FALSE 失敗
   */
  public boolean doRequestCheckoutCancel(ALAction action, RunData rundata,
      Context context) {
    try {

      if (!doCheckSecurity(rundata, context)) {
        return false;
      }

      init(action, rundata, context);

      doCheckAclPermission(rundata, context,
          ALAccessControlConstants.VALUE_ACL_UPDATE);

      action.setMode(DocumentConstants.MODE_REQUEST_CHECKOUT_CANCEL);

      setMode(action.getMode());

      ArrayList msgList = new ArrayList();
      setValidator();
      
      // オブジェクトモデルを取得
      ImwTDocumentFile oldfile = DocumentUtils.getImwTDocumentFile(rundata,
          context);
      if (oldfile == null) {
        msgList.add("文書が存在しません。");
        action.addErrorMessages(msgList);
        action.putData(rundata, context);
        return false;
      }

      // チェックアウト中で無ければ失敗
      if (!("1".equals(oldfile.getStatus()))) {
        msgList.add("チェックアウトされていません。");
        action.addErrorMessages(msgList);
        action.putData(rundata, context);
        return false;
      }

      // ログインユーザがチェックアウト者で無ければ失敗
      int current_user_id = ALEipUtils.getUserId(rundata);
      Integer checkoutUserId = oldfile.getCheckoutUserId();
      if (checkoutUserId == null || current_user_id != (int) checkoutUserId) {
        msgList.add("別のユーザーによりチェックアウトされています。");
        action.addErrorMessages(msgList);
        action.putData(rundata, context);
        return false;
      }
      
      boolean res = (setFormData(rundata, context, msgList)
          && validate(msgList) && requestFormData(rundata, context, msgList));
      
      if (!res) {
        action.setMode(ALEipConstants.MODE_EDIT_FORM);
        setMode(action.getMode());
      }
      action.setResultData(this);
      action.addErrorMessages(msgList);
      action.putData(rundata, context);

      return res;
    } catch (ALPermissionException e) {
      ALEipUtils.redirectPermissionError(rundata);
      return false;
    } catch (ALPageNotFoundException e) {
      ALEipUtils.redirectPageNotFound(rundata);
      return false;
    } catch (ALDBErrorException e) {
      ALEipUtils.redirectDBError(rundata);
      return false;
    }
  }

  public boolean checkoutCancelFormData(RunData rundata, Context context,
      ArrayList msgList) {
    try {

      // オブジェクトモデルを取得
      ImwTDocumentFile oldfile = DocumentUtils.getImwTDocumentFile(rundata,
          context);
      if (oldfile == null) {
        msgList.add("文書が存在しません。");
        return false;
      }

      // チェックアウト中で無ければ失敗
      if (!("1".equals(oldfile.getStatus()))) {
        msgList.add("チェックアウトされていません。");
        return false;
      }

      // ログインユーザがチェックアウト者で無ければ失敗
      int current_user_id = ALEipUtils.getUserId(rundata);
      Integer checkoutUserId = oldfile.getCheckoutUserId();
      if (checkoutUserId == null || current_user_id != (int) checkoutUserId) {
        msgList.add("別のユーザーによりチェックアウトされています。");
        return false;
      }

      // ファイルのステータス
      oldfile.setStatus("0");

      // ファイルのチェックアウトID     ダミーの-1を入れる
      //oldfile.setCheckoutUserId(null);
      oldfile.setCheckoutUserId(Integer.valueOf(-1));

      // ファイルのチェックアウト日
      oldfile.setCheckoutDate(null);

      // ファイルを登録
      dataContext.commitChanges();

      return true;
    } catch (Exception ex) {
      dataContext.rollbackChanges();
      logger.error("Exception", ex);
      return false;
    }
  }

  /**
   * データをチェックインします。
   * 
   * @param action
   * @param rundata
   * @param context
   * @return TRUE 成功 FALSE 失敗
   */
  public boolean doCheckin(ALAction action, RunData rundata, Context context) {
    try {

      if (!doCheckSecurity(rundata, context)) {
        return false;
      }

      init(action, rundata, context);

      doCheckAclPermission(rundata, context,
          ALAccessControlConstants.VALUE_ACL_UPDATE);

      //action.setMode(ALEipConstants.MODE_CHECKIN);

      setMode(action.getMode());

      ArrayList msgList = new ArrayList();
      setValidator();
      boolean res = (setFormData(rundata, context, msgList)
          && validate(msgList) && checkinFormData(rundata, context, msgList));
      if (!res) {
        action.setMode(ALEipConstants.MODE_EDIT_FORM);
        setMode(action.getMode());
      }
      action.setResultData(this);
      action.addErrorMessages(msgList);
      action.putData(rundata, context);

      return res;
    } catch (ALPermissionException e) {
      ALEipUtils.redirectPermissionError(rundata);
      return false;
    } catch (ALPageNotFoundException e) {
      ALEipUtils.redirectPageNotFound(rundata);
      return false;
    } catch (ALDBErrorException e) {
      ALEipUtils.redirectDBError(rundata);
      return false;
    }
  }

  protected boolean checkinFormData(RunData rundata, Context context,
      ArrayList msgList) {
    boolean res = false;
    try {

      // ログインユーザID
      int uid = ALEipUtils.getUserId(rundata);
      
      String localFilePath = null;
      
      // 新旧オブジェクトモデルの取得
      ImwTDocumentFile file, oldfile;
      
      if(DocumentConstants.MODE_REQAGAIN_CHECKIN.equals(getMode())){
        // チェックイン再申請の場合
        
        // 新規オブジェクト
        file = DocumentUtils.getImwTDocumentFile(rundata, context);
        if (file == null){
          return false;
        }
        
        // 旧オブジェクト
        oldfile = LibDocumentUtils.getLastDoc(file.getDocId());
        if (oldfile == null){
          msgList.add("文書が存在しません。");
          return false;
        }

        // ログインユーザが申請者以外なら失敗        
        ImwTDocumentRequestMap reqMap = DocumentUtils
            .getImwTDocumentRequestMapByDocId(file.getDocId());
        if (reqMap == null || reqMap.getRequestUserId() == null
            || uid != reqMap.getRequestUserId().intValue()) {
          msgList.add("ログインユーザーが申請者ではありません。");
          return false;
        }
        
        // 再申請の条件を満たしていなければ失敗
        if (!DocumentUtils.isDocReqAgain(file.getDocId())){
          msgList.add("再申請の条件を満たしていません。");
          return false;
        }

        // ファイルを新規追加した場合、既存のファイルパスを取得
        if (fileids != null && !"I".equals(fileids[0])) {
          localFilePath = file.getFilePath();
        }
       
      } else {
        // チェックインまたはチェックイン申請時
        
        // 新規オブジェクトモデル
        file = (ImwTDocumentFile) dataContext
            .createAndRegisterNewObject(ImwTDocumentFile.class);
        
        // 旧オブジェクトモデルを取得
        oldfile = DocumentUtils.getImwTDocumentFile(rundata,
            context);
        if (oldfile == null) {
          msgList.add("文書が存在しません。");
          return false;
        }
        
        //　申請中チェック
        if(DocumentUtils.isDocRequesting(oldfile)){
          msgList.add("このファイルは既に申請されています。");
          return false;
        }
      }
      
      // チェック処理
      // チェックアウト中で無ければ失敗
      if (!("1".equals(oldfile.getStatus()))) {
        msgList.add("チェックアウトされていません。");
        return false;
      }

      // ログインユーザがチェックアウト者で無ければ失敗
      Integer checkoutUserId = oldfile.getCheckoutUserId();
      if (checkoutUserId == null || uid != (int) checkoutUserId) {
        msgList.add("別のユーザーによりチェックアウトされています。");
        return false;
      }
      

      // アップロードしたファイルは存在するか
      boolean is_upload = true;
      if (fileuploadList == null) {
        is_upload = false;
      }
      if (is_upload) {
        // アップロードが確認できた場合
        FileuploadLiteBean filebean = (FileuploadLiteBean) fileuploadList
            .get(0);
        String filename = FileuploadUtils.getNewFileName(DocumentUtils
            .getSaveDirPath(org_id));
        // ファイルの移動先
        File destFile = new File(DocumentUtils
            .getAbsolutePath(org_id, filename));

        // 一時保存の添付ファイル
        File srcFile = FileuploadUtils.getAbsolutePath(org_id, uid, folderName,
            filebean.getFileId());

        // ファイルの移動
        FileuploadUtils.copyFile(srcFile, destFile);

        // ファイル名
        file.setFileName(file_name.getValue());

        // ファイルサイズ
        double fileSize = Math.ceil(destFile.length() / 1024.0);
        file.setFileSize(Long.valueOf((long) fileSize));

        // ファイルパス
        file.setFilePath(DocumentUtils.getRelativePath(filename));

      }
      // ファイルがアップロードされていない
      else {
        // チェックイン、チェックイン申請時はエラーにする。
        if (!DocumentConstants.MODE_REQAGAIN_CHECKIN.equals(getMode())){
          msgList.add("チェックインファイルを選択してください。");
          return false;
        }
      }

      ImwTDocumentFolder folder = (ImwTDocumentFolder) DataObjectUtils
          .objectForPK(dataContext, ImwTDocumentFolder.class, Integer
              .valueOf((int) folder_id.getValue()));

      // 作成者
      file.setCreateUserId(oldfile.getCreateUserId());
      // 作成日
      file.setCreateDate(oldfile.getCreateDate());

      // 親フォルダ
      //file.setImwTDocumentFolder(folder);
      file.setImwTDocumentFolder(oldfile.getImwTDocumentFolder());

      // ファイルタイトル
      file.setFileTitle(file_title.getValue());
      // ファイル名
      file.setFileName(file_name.getValue());

      // ファイル
      // file.setFile(fileData);
      // メモ
      file.setNote(note.getValue());

      // 更新者
      file.setUpdateUserId(Integer.valueOf(uid));

      // 更新日
      file.setUpdateDate(Calendar.getInstance().getTime());

      // リビジョン
      if ("MJ".equals(fileRev.getValue())) {
        file.setFileRevMj(oldfile.getFileRevMj() + 1);
        file.setFileRevMn(0);
      } else {
        file.setFileRevMj(oldfile.getFileRevMj());
        file.setFileRevMn(oldfile.getFileRevMn() + 1);
      }

      // 公開終了日
      if (open_end_date != null) {
        file.setOpenEndDate(open_end_date.getTime());
      }

      // 保存終了日
      if (save_end_date != null) {
        file.setSaveEndDate(save_end_date.getTime());
      }

      //　文書ID
      Integer docId = oldfile.getDocId();
      if(docId == null){
        dataContext.rollbackChanges();
        return false;
      }
      file.setDocId(docId);

      // 申請状態
      Integer requestStatus = null;
      if (ALEipConstants.MODE_CHECKIN.equals(getMode())) {
        requestStatus = Integer.valueOf(0);
      } else {
        requestStatus = Integer.valueOf(1);
      }

      // 関連文書
      if (DocumentConstants.MODE_REQUEST_CHECKIN.equals(getMode())) {
        // チェックイン申請の場合
        if (!DocumentUtils.insertRelationFilesForRequestCheckin(rundata, context, dataContext,
            docId, requestStatus, relationuploadList, folderName, msgList)) {
          dataContext.rollbackChanges();
          return false;
        }
      } else {
        // チェックイン・チェックイン再申請の場合
        if (!DocumentUtils.insertRelationFiles(rundata, context, dataContext,
            docId, requestStatus, relationuploadList, folderName, msgList)) {
          dataContext.rollbackChanges();
          return false;
        }
      }

      // チェックインコメント
      file.setCheckinComment(checkinComment.getValue());

      //System.out.println("checkval = " + checkinComment.getValue());

      // アクセス権の削除
      if(!LibDocumentUtils
          .deleteFileMap(dataContext, file.getDocId(), requestStatus)){
        dataContext.rollbackChanges();
        return false;
      }
      
      // 閲覧権限
      if (is_member_read) {
        if(!insertFileMap(memberReadGroupList, memberReadUserList, docId, Integer
            .valueOf(0), requestStatus)){
          dataContext.rollbackChanges();
          return false;
        }
      } else {
        if(!insertFileMapAllUser(docId, Integer.valueOf(0), requestStatus)){
          dataContext.rollbackChanges();
          return false;
        }
      }

      // 編集権限
      if (is_member_edit) {
        if(!insertFileMap(memberEditGroupList, memberEditUserList, docId, Integer
            .valueOf(1), requestStatus)){
          dataContext.rollbackChanges();
          return false;
        }
      } else {
        if(!insertFileMapAllUser(docId, Integer.valueOf(1), requestStatus)){
          dataContext.rollbackChanges();
          return false;
        }
      }
      
      if (ALEipConstants.MODE_CHECKIN.equals(getMode())){
        // チェックイン時
        // チェックアウトID      ダミーの-1を入れる
        file.setCheckoutUserId(Integer.valueOf(-1));
      }

      // ステータス
      if (ALEipConstants.MODE_CHECKIN.equals(getMode())){
        file.setStatus("0");
      } else {
        file.setStatus("3");
      }

      // チェックイン時、旧ファイルを修正
      if (ALEipConstants.MODE_CHECKIN.equals(getMode())) {
        // 旧ファイルのステータス
        oldfile.setStatus("2");

        // 旧ファイルのチェックアウトID ダミーの-1を入れる
        // oldfile.setCheckoutUserId(null);
        oldfile.setCheckoutUserId(Integer.valueOf(-1));

        // 旧ファイルのチェックアウト日
        oldfile.setCheckoutDate(null);
      } else if (DocumentConstants.MODE_REQUEST_CHECKIN.equals(getMode())
          || DocumentConstants.MODE_REQAGAIN_CHECKIN.equals(getMode())){
        // チェックイン申請時・再申請時、チェックアウトユーザとチェックアウト時刻をコピー        
        file.setCheckoutUserId(oldfile.getCheckoutUserId());
        file.setCheckoutDate(oldfile.getCheckoutDate());
      }
 
      //　チェックインの場合
      if (ALEipConstants.MODE_CHECKIN.equals(getMode())) {
        // DBに反映
        dataContext.commitChanges();
      } else {      
        // 申請もしくは再申請の場合

        // ワークフロー依頼オブジェクトの作成
        EipTWorkflowRequest request = (EipTWorkflowRequest) dataContext
            .createAndRegisterNewObject(EipTWorkflowRequest.class);

        String[] relationids = rundata.getParameters().getStrings("relations");

        // 申請内容
        String note = DocumentUtils.getNewFileInfo(file, is_member_read,
            is_member_edit, memberReadGroupList, memberReadUserList,
            memberEditGroupList, memberEditUserList, relationids,
            relationuploadList);
        // 申請処理
        if (!DocumentUtils.insertRequest(rundata, dataContext, file, request,
            getMode(), note, workflowMemberList, is_saved_route, route_id
                .getValue())){
          return false;
        }
        
        // DB反映
        dataContext.commitChanges();

        // 申請後処理（イベントログの追加、新着情報の追加、次申請者へのメール送信）
        DocumentUtils.insertRequestEnd(rundata, dataContext,file, request,
            workflowMemberList);

        // チェックイン再申請時
        if (DocumentConstants.MODE_REQAGAIN_CHECKIN.equals(getMode())) {
          if (localFilePath != null && !"".equals(localFilePath)) {
            // ファイルを新規登録した場合は、
            // ローカルファイルに保存されているファイルを削除する．
            File local_file = null;
            local_file = new File(DocumentUtils.getSaveDirPath(org_id)
                + localFilePath);
            if (local_file.exists()) {
              local_file.delete();
            }
          }
        }
      }      
      
      // イベントログに保存
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(
          file.getFileId(), ALEventlogConstants.PORTLET_TYPE_DOCUMENT_FILE,
          file_title.getValue());

      File folder_tmp = FileuploadUtils.getFolder(org_id, uid, folderName);
      // 添付ファイル保存先のフォルダを削除
      FileuploadUtils.deleteFolder(folder_tmp);

      res = true;
    } catch (Exception ex) {
      dataContext.rollbackChanges();
      logger.error("Exception", ex);
      return false;
    }
    return res;
  }
  
  /**
   * データを削除申請します。
   * 
   * @param action
   * @param rundata
   * @param context
   * @return TRUE 成功 FALSE 失敗
   */
  public boolean doRequestDelete(ALAction action, RunData rundata, Context context) {
    try {

      if (!doCheckSecurity(rundata, context)) {
        return false;
      }

      init(action, rundata, context);

      //doCheckAclPermission(rundata, context,
        //  ALAccessControlConstants.VALUE_ACL_UPDATE);

      action.setMode(DocumentConstants.MODE_REQUEST_DELETE);

      setMode(action.getMode());

      ArrayList msgList = new ArrayList();
      //setValidator();
      
      
      ImwTDocumentFile file = DocumentUtils.getImwTDocumentFile(rundata, context);
      if (file==null){
        msgList.add("文書が存在しません。");
        action.addErrorMessages(msgList);
        action.putData(rundata, context);
        return false;
      }
      // チェックアウトされている場合に、ログインユーザがチェックアウト者で無ければ失敗
      int current_user_id = ALEipUtils.getUserId(rundata);
      Integer checkoutUserId = file.getCheckoutUserId();
      if ("1".equals(file.getStatus())
          &&( checkoutUserId == null 
              || current_user_id != (int) checkoutUserId)) {
        msgList.add("別のユーザーによりチェックアウトされているため削除申請できません。");
        action.addErrorMessages(msgList);
        action.putData(rundata, context);
        return false;
      }
      
      boolean res = (setFormData(rundata, context, msgList)
          && validate(msgList) && requestFormData(rundata, context, msgList));
     
      if (!res) {
        action.setMode(ALEipConstants.MODE_EDIT_FORM);
        setMode(action.getMode());
      }
      action.setResultData(this);
      action.addErrorMessages(msgList);
      action.putData(rundata, context);

      return res;
    //} catch (ALPermissionException e) {
     // ALEipUtils.redirectPermissionError(rundata);
     //return false;
    } catch (ALPageNotFoundException e) {
      ALEipUtils.redirectPageNotFound(rundata);
      return false;
    } catch (ALDBErrorException e) {
      ALEipUtils.redirectDBError(rundata);
      return false;
    }
  }

  public int getFileId() {
    return file_id;
  }

  public String getFolderName() {
    return folderName.toString();
  }

  /**
   *
   *
   * @return
   */
  public ALNumberField getFolderId() {
    return folder_id;
  }

  /**
   * ファイルタイトルを取得する． <BR>
   *
   * @return
   */
  public ALStringField getFileTitle() {
    return file_title;
  }

  /**
   * ファイル名を取得する． <BR>
   *
   * @return
   */
  public ALStringField getFileName() {
    return file_name;
  }
  
  /**
   * 現在有効なファイルのファイル名を取得する． <BR>
   *
   * @return
   */
  public String getOldFileName() {
    if(this.oldDocFile!=null){
      return oldDocFile.getFileName();
    } else {
      return "";
    }
  }

  /**
   * 関連文書名を取得する． <BR>
   *
   * @return
   */
  public ALStringField getRelationName() {
    return relation_name;
  }

  /**
   * ファイルサイズを取得する． <BR>
   *
   * @return
   */
  public ALNumberField getFileSize() {
    return file_size;
  }

  /**
   * メモを取得する． <BR>
   *
   * @return
   */
  public ALStringField getNote() {
    return note;
  }

  public ArrayList getFolderHierarchyList() {
    return folder_hierarchy_list;
  }

  public FolderInfo getSelectedFolderInfo() {
    return selected_folderinfo;
  }

  /**
   * チェックインコメントを取得する． <BR>
   *
   * @return
   */
  public ALStringField getCheckinComment() {
    return checkinComment;
  }

  /**
   * 閲覧グループリストを取得する． <BR>
   *
   * @return
   */
  public List getReadGroup() {
    return initReadGroupList;
  }

  /**
   * 閲覧ユーザリストを取得する． <BR>
   *
   * @return
   */
  public List getReadUser() {
    return initReadUserList;
  }

  /**
   * 編集グループリストを取得する． <BR>
   *
   * @return
   */
  public List getEditGroup() {
    return initEditGroupList;
  }

  /**
   * 閲覧ユーザリストを取得する． <BR>
   *
   * @return
   */
  public List getEditUser() {
    return initEditUserList;
  }

  /**
   * 閲覧メンバーの表示の有無を取得． <BR>
   *
   * @return
   */
  public boolean getReadMemberDisp() {
    return (is_member_read);
  }

  /**
   * 編集メンバーの表示の有無を取得． <BR>
   *
   * @return
   */
  public boolean getEditMemberDisp() {
    return (is_member_edit);
  }

  /**
   * 公開終了日時を取得します。
   *
   * @return
   */
  public ALDateTimeField getOpenEndDate() {
    if (open_end_date != null) {
      ALDateTimeField tmpDate = new ALDateTimeField("yyyy/MM/dd");
      tmpDate.setValue(open_end_date.getTime());
      return tmpDate;
    } else {
      return null;
    }
  }

  /**
   * 保存終了日時を取得します。
   *
   * @return
   */
  public ALDateTimeField getSaveEndDate() {
    if (save_end_date != null) {
      ALDateTimeField tmpDate = new ALDateTimeField("yyyy/MM/dd");
      tmpDate.setValue(save_end_date.getTime());
      return tmpDate;
    } else {
      return null;
    }
  }

  /**
   *
   * @param id
   * @return
   */
  public boolean isMatch(int id1, long id2) {
    return id1 == (int) id2;
  }

  public List getAttachmentFileNameList() {
    return fileuploadList;
  }

  public List getRelationFileNameList() {
    return relationuploadList;
  }

  public List getInitRelationFileNameList() {
    return initRelationList;
  }

  public String getFolderPosition() {
    return DocumentUtils.getFolderPosition(folder_hierarchy_list,
        (int) folder_id.getValue());
  }

  /**
   * 申請モードを取得します。
   *
   * @return　申請モード
   */
  public int getRequestMode() {
    boolean coop = DocumentUtils.isDocWorkflowCoop();
    // （ログインユーザが文書管理者 AND 申請中でない）　AND　ワークフロー連携オフ
    ImwTDocumentRequestMap reqMap = DocumentUtils
        .getImwTDocumentRequestMapByDocId(this.docId);
    if ((this.isDocAdmin && reqMap == null) || !coop) {
      // 通常
      return 0;
    }
    // NOT （ログインユーザが文書管理者 AND 申請中でない） AND ワークフロー連携オン
    else {
      if (!this.isDocReqAgain) {
        // 申請
        return 1;
      } else {
        // 再申請
        return 2;
      }
    }
  }

  /**
   * 申請種類を取得します。
   *
   * @return　申請種類
   */
  public Integer getRequestType() {
    Integer type = DocumentUtils.getRequestTypeByDocId(this.docId);
    if (type == null) {
      type = Integer.valueOf(0);
    }
    return type;
  }

  /**
   * @return
   */
  public boolean getIsSavedRoute() {
    return is_saved_route;
  }

  /**
   * 申請経路一覧を取得します。 <BR>
   *
   * @return
   */
  public List getRouteList() {
    return routeList;
  }

  public String getRouteH() {
    StringBuffer routeun = new StringBuffer();
    String username;

    if (route.getValue() != null && !"".equals(route.getValue())) {
      StringTokenizer st = new StringTokenizer(route.getValue(), ",");
      while (st.hasMoreTokens()) {
        username = WorkflowUtils.getName(st.nextToken());
        routeun.append(username);
        routeun.append(" -> ");
      }
      routeun.append("完了");

      return routeun.toString();
    }
    return "";
  }

  /**
   * 申請経路IDを取得します。 <BR>
   *
   * @return
   */
  public ALNumberField getRouteId() {
    return route_id;
  }

  /**
   * グループメンバーを取得します。 <BR>
   *
   * @return
   */
  public List getWorkflowMemberList() {
    return workflowMemberList;
  }

  /**
   * ログインユーザーが文書管理システム管理者かどうかを取得します。 <BR>
   *
   * @return
   */
  public boolean getIsDocAdmin() {
    return this.isDocAdmin;
  }
  
  /**
   * バージョンを取得します
   * @return バージョン
   */
  public String getFileRev(){
    if (docFile==null
        || docFile.getFileRevMj() == null
        || docFile.getFileRevMn() == null){
      return "";
    } else {
      return docFile.getFileRevMj().toString() + "."
              + docFile.getFileRevMn().toString();
    }
  }
  
  /**
   * バージョンの差分を取得します
   * @return　String
   */
  public String getFileRevUp(){
    if (docFile==null || oldDocFile==null
        || docFile.getFileRevMj() == null 
        || docFile.getFileRevMn() == null
        || oldDocFile.getFileRevMj() == null
        || oldDocFile.getFileRevMn() == null){
      return "";
    } else {
      return String.valueOf(docFile.getFileRevMj()-oldDocFile.getFileRevMj())
            + "."
            + String.valueOf(docFile.getFileRevMn()-oldDocFile.getFileRevMn());
    }
  }
  
  /**
   * アクセス権限チェック用メソッド。<br />
   * アクセス権限の機能名を返します。
   *
   * @return
   */
  public String getAclPortletFeature() {
    return ALAccessControlConstants.POERTLET_FEATURE_DOCUMENT_FILE;
  }

}
