/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * http://aipostyle.com/
 * 
 * Copyright(C) 2009 avanza Co.,Ltd. All rights reserved.
 * http://www.avnz.co.jp/
 * 
 * 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.circulation.util;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import javax.imageio.ImageIO;

import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
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.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.eip.cayenne.om.portlet.AvzTCirculationCategory;
import com.aimluck.eip.cayenne.om.portlet.AvzTCirculationFile;
import com.aimluck.eip.cayenne.om.portlet.AvzTCirculationRequest;
import com.aimluck.eip.cayenne.om.portlet.AvzTCirculationRequestMap;
import com.aimluck.eip.cayenne.om.portlet.auto._AvzTCirculationCategory;
import com.aimluck.eip.cayenne.om.portlet.auto._AvzTCirculationFile;
import com.aimluck.eip.cayenne.om.portlet.auto._AvzTCirculationRequest;
import com.aimluck.eip.cayenne.om.portlet.auto._AvzTCirculationRequestMap;
import com.aimluck.eip.circulation.CirculationCategoryResultData;
import com.aimluck.eip.circulation.CirculationDetailResultData;
import com.aimluck.eip.circulation.CirculationResponseRecordData;
import com.aimluck.eip.circulation.CirculationSelectData;
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.fileupload.beans.FileuploadBean;
import com.aimluck.eip.fileupload.beans.FileuploadLiteBean;
import com.aimluck.eip.fileupload.util.FileuploadUtils;
import com.aimluck.eip.orm.Database;
import com.aimluck.eip.orm.query.ResultList;
import com.aimluck.eip.orm.query.SelectQuery;
import com.aimluck.eip.services.storage.ALStorageService;
import com.aimluck.eip.util.ALEipUtils;

/**
 * 回覧板のユーティリティクラスです。 <BR>
 * 
 */
public class CirculationUtils {

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

  /** 未確認の人 */
  public static final String DB_STATUS_REQUEST = "R";

  /** 確認済みの人 */
  public static final String DB_STATUS_CONFIRM = "C";

  /** 回覧の添付ファイルを保管するディレクトリの指定 */
  private static final String FOLDER_FILEDIR_CIRCULATION =
    JetspeedResources.getString("aipo.filedir", "");

  /** 回覧の添付ファイルを保管するディレクトリのカテゴリキーの指定 */
  protected static final String CATEGORY_KEY =
    JetspeedResources.getString("aipo.circulation.categorykey", "");

  /** 期限状態（期限前） */
  public static final int LIMIT_STATE_BEFORE = -1;

  /** 期限状態（期限当日） */
  public static final int LIMIT_STATE_TODAY = 0;

  /** 期限状態（期限後） */
  public static final int LIMIT_STATE_AFTER = 1;

  /** すべて確認 */
  public static final String DB_PROGRESS_CONFIRM = "C";

  /** 確認中 */
  public static final String DB_PROGRESS_WAIT = "W";

  /** 締め切り日指定無しの場合のダミー年 */
  public static final int DUMMY_YEAR = 9999;

  /**
   * Circulation オブジェクトモデルを取得します。 <BR>
   * 
   * @param rundata
   * @param context
   * @return
   */
  public static AvzTCirculationRequest getAvzTCirculationRequest(
      RunData rundata, Context context) throws ALPageNotFoundException {

    String avz_t_circulation_requestid =
      ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);

    try {
      if (avz_t_circulation_requestid == null
        || Integer.valueOf(avz_t_circulation_requestid) == null) {
        // avz_t_circulation_request IDが空の場合
        logger.debug("[avz_t_circulation_request] Empty ID...");
        return null;
      }

      SelectQuery<AvzTCirculationRequest> query =
        Database.query(AvzTCirculationRequest.class);
      Expression exp1 =
        ExpressionFactory.matchDbExp(
          _AvzTCirculationRequest.REQUEST_ID_PK_COLUMN,
          avz_t_circulation_requestid);

      query.setQualifier(exp1);

      ResultList<AvzTCirculationRequest> avz_t_circulation_requests =
        query.getResultList();
      if (avz_t_circulation_requests == null
        || avz_t_circulation_requests.size() == 0) {
        // 指定したavz_t_circulation_request IDのレコードが見つからない場合
        logger.debug("[CirculationUtils] Not found ID...");
        return null;
      }

      return avz_t_circulation_requests.get(0);

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

  /**
   * カテゴリの一覧を取得する。
   * 
   * @param rundata
   * @param context
   */
  public static List<CirculationCategoryResultData> loadCategoryList(
      RunData rundata, Context context) {
    try {
      // カテゴリ一覧
      List<CirculationCategoryResultData> categoryList =
        new ArrayList<CirculationCategoryResultData>();

      SelectQuery<AvzTCirculationCategory> query =
        Database.query(AvzTCirculationCategory.class);
      ResultList<AvzTCirculationCategory> aList = query.getResultList();

      int size = aList.size();
      for (int i = 0; i < size; i++) {
        AvzTCirculationCategory record = aList.get(i);
        CirculationCategoryResultData rd = new CirculationCategoryResultData();
        rd.initField();
        rd.setCategoryId(record.getCategoryId().longValue());
        rd.setCategoryName(record.getCategoryName());
        rd.setOrderTemplate(record.getTemplate());
        categoryList.add(rd);
      }

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

  /**
   * 回覧板カテゴリ オブジェクトモデルを取得します。 <BR>
   * 
   * @param rundata
   * @param context
   * @param mode_update
   * @return
   */
  public static AvzTCirculationCategory getAvzTCirculationCategory(
      RunData rundata, Context context) {
    String categoryid =
      ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);
    try {
      if (categoryid == null || Integer.valueOf(categoryid) == null) {
        // Request IDが空の場合
        logger.debug("[CirculationUtils] Empty ID...");
        return null;
      }

      SelectQuery<AvzTCirculationCategory> query =
        Database.query(AvzTCirculationCategory.class);
      Expression exp1 =
        ExpressionFactory.matchDbExp(
          _AvzTCirculationCategory.CATEGORY_ID_PK_COLUMN,
          categoryid);
      query.setQualifier(exp1);

      ResultList<AvzTCirculationCategory> categories = query.getResultList();

      if (categories == null || categories.size() == 0) {
        // 指定したカテゴリIDのレコードが見つからない場合
        logger.debug("[CirculationUtils] Not found ID...");
        return null;
      }
      return (categories.get(0));
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return null;
    }
  }

  /**
   * リクエストIDにひもづくAvzTCirculationRequestMapレコードを取得します。
   * 
   * @param request
   * @return
   */
  public static ResultList<AvzTCirculationRequestMap> getAvzTCirculationRequestMaps(
      AvzTCirculationRequest request) {
    try {
      SelectQuery<AvzTCirculationRequestMap> query =
        Database.query(AvzTCirculationRequestMap.class);
      Expression exp =
        ExpressionFactory.matchDbExp(
          _AvzTCirculationRequestMap.TO_AVZ_TCIRCULATION_REQUEST_PROPERTY
            + "."
            + _AvzTCirculationRequest.REQUEST_ID_PK_COLUMN,
          request.getRequestId());
      query.setQualifier(exp);

      ResultList<AvzTCirculationRequestMap> maps = query.getResultList();

      if (maps == null || maps.size() == 0) {
        // 指定した Request IDのレコードが見つからない場合
        logger.debug("[CirculationSelectData] Not found ID...");
        return null;
      }
      return maps;
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return null;
    }
  }

  public static ResultList<AvzTCirculationRequestMap> getAvzTCirculationRequestMap(
      RunData rundata, Context context, AvzTCirculationRequest request) {
    try {
      int uid = ALEipUtils.getUserId(rundata);

      SelectQuery<AvzTCirculationRequestMap> query =
        Database.query(AvzTCirculationRequestMap.class);

      Expression exp1 =
        ExpressionFactory.matchDbExp(
          _AvzTCirculationRequestMap.TO_AVZ_TCIRCULATION_REQUEST_PROPERTY
            + "."
            + _AvzTCirculationRequest.REQUEST_ID_PK_COLUMN,
          request.getRequestId());

      Expression exp2 =
        ExpressionFactory.matchExp(
          _AvzTCirculationRequest.USER_ID_PROPERTY,
          uid);

      query.setQualifier(exp1.andExp(exp2));

      ResultList<AvzTCirculationRequestMap> maps = query.getResultList();

      if (maps == null || maps.size() == 0) {
        // 指定した Request IDのレコードが見つからない場合
        logger.debug("[CirculationSelectData] Not found ID...");
        return null;
      }
      return maps;
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return null;
    }
  }

  public static int getCountOfAvzTCirculationRequestMap(
      AvzTCirculationRequest request) {
    try {
      SelectQuery<AvzTCirculationRequestMap> query =
        Database.query(AvzTCirculationRequestMap.class);

      Expression exp11 =
        ExpressionFactory.matchDbExp(
          _AvzTCirculationRequestMap.TO_AVZ_TCIRCULATION_REQUEST_PROPERTY
            + "."
            + _AvzTCirculationRequest.REQUEST_ID_PK_COLUMN,
          request.getRequestId());

      query.setQualifier(exp11);

      ResultList<AvzTCirculationRequestMap> maps = query.getResultList();

      if (maps == null) {
        // 指定した Request IDのレコードが見つからない場合
        logger.debug("[CirculationSelectData] Not found ID...");
        return 0;
      }
      return maps.size();
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return 0;
    }
  }

  public static int getCountOfConfirmedAvzTCirculationRequestMap(
      AvzTCirculationRequest request) {
    try {
      SelectQuery<AvzTCirculationRequestMap> query =
        Database.query(AvzTCirculationRequestMap.class);

      Expression exp11 =
        ExpressionFactory.matchDbExp(
          _AvzTCirculationRequestMap.TO_AVZ_TCIRCULATION_REQUEST_PROPERTY
            + "."
            + _AvzTCirculationRequest.REQUEST_ID_PK_COLUMN,
          request.getRequestId());

      Expression exp12 =
        ExpressionFactory.matchExp(
          _AvzTCirculationRequestMap.STATUS_PROPERTY,
          CirculationUtils.DB_STATUS_CONFIRM);

      query.setQualifier(exp11.andExp(exp12));

      ResultList<AvzTCirculationRequestMap> maps = query.getResultList();

      if (maps == null) {
        // 指定した Request IDのレコードが見つからない場合
        logger.debug("[CirculationSelectData] Not found ID...");
        return 0;
      }
      return maps.size();
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return 0;
    }
  }

  /**
   * Request オブジェクトモデルを取得します。 <BR>
   * 
   * @param rundata
   * @param context
   * @param mode_update
   * @return
   */
  public static AvzTCirculationRequest getAvzTCirculationRequestForOwner(
      RunData rundata, Context context) {
    String requestid =
      ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);
    try {
      if (requestid == null || Integer.valueOf(requestid) == null) {
        // Request IDが空の場合
        logger.debug("[CirculationUtils] Empty ID...");
        return null;
      }

      SelectQuery<AvzTCirculationRequest> query =
        Database.query(AvzTCirculationRequest.class);
      Expression exp1 =
        ExpressionFactory.matchDbExp(
          _AvzTCirculationRequest.REQUEST_ID_PK_COLUMN,
          requestid);
      query.setQualifier(exp1);

      Expression exp2 =
        ExpressionFactory.matchExp(
          _AvzTCirculationRequest.USER_ID_PROPERTY,
          Integer.valueOf(ALEipUtils.getUserId(rundata)));
      query.andQualifier(exp2);

      ResultList<AvzTCirculationRequest> requests = query.getResultList();

      if (requests == null || requests.size() == 0) {
        // 指定した Request IDのレコードが見つからない場合
        logger.debug("[CirculationUtils] Not found ID...");
        return null;
      }
      return (requests.get(0));
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return null;
    }
  }

  /**
   * ユーザ毎のルート保存先（絶対パス）を取得します。
   * 
   * @param uid
   * @return
   */
  // public static String getSaveDirPath(String orgId, int uid) {
  // ALOrgUtilsHandler handler =
  // ALOrgUtilsFactoryService.getInstance().getOrgUtilsHandler();
  // File path =
  // new File(handler.getDocumentPath(
  // FOLDER_FILEDIR_CIRCULATION,
  // orgId,
  // CATEGORY_KEY)
  // + File.separator
  // + uid);
  // if (!path.exists()) {
  // path.mkdirs();
  // }
  // return path.getAbsolutePath();
  // }
  public static String getSaveDirPath(String orgId, int uid) {
    return ALStorageService.getDocumentPath(
      FOLDER_FILEDIR_CIRCULATION,
      CATEGORY_KEY + ALStorageService.separator() + uid);
  }

  /**
   * ユーザ毎の保存先（相対パス）を取得します。
   * 
   * @param uid
   * @return
   */
  public static String getRelativePath(String fileName) {
    return new StringBuffer().append("/").append(fileName).toString();
  }

  // public static String getAbsolutePath(String orgId, int uid, String
  // fileName) {
  // ALOrgUtilsHandler handler =
  // ALOrgUtilsFactoryService.getInstance().getOrgUtilsHandler();
  // StringBuffer sb =
  // new StringBuffer()
  // .append(
  // handler.getDocumentPath(
  // FOLDER_FILEDIR_CIRCULATION,
  // orgId,
  // CATEGORY_KEY))
  // .append(File.separator)
  // .append(uid);
  // File f = new File(sb.toString());
  // if (!f.exists()) {
  // f.mkdirs();
  // }
  // return sb.append(File.separator).append(fileName).toString();
  // }

  /**
   * 回覧板カテゴリ オブジェクトモデルを取得します。 <BR>
   * 
   * @param rundata
   * @param context
   * @return
   */
  public static AvzTCirculationCategory getAvzTCirculationCategory(
      Long category_id) {
    try {
      AvzTCirculationCategory category =
        Database.get(AvzTCirculationCategory.class, category_id);

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

  public static boolean insertFileDataDelegate(RunData rundata,
      Context context, AvzTCirculationRequest request,
      AvzTCirculationRequest oldrequest, List fileuploadList,
      String folderName, List<String> msgList) {

    // DataContext dataContext =
    // DatabaseOrmService.getInstance().getDataContext();
    int uid = ALEipUtils.getUserId(rundata);
    // String org_id = DatabaseOrmService.getInstance().getOrgId(rundata);
    String org_id = Database.getDomainName();
    String[] fileids = rundata.getParameters().getStrings("attachments");

    // fileidsがnullなら、ファイルがアップロードされていないので、trueを返して終了
    if (fileids == null) {
      return true;
    }

    int fileIDsize;
    if (fileids[0].equals("")) {
      fileIDsize = 0;
    } else {
      fileIDsize = fileids.length;
    }
    // 送られてきたFileIDの個数とDB上の当該RequestID中の添付ファイル検索を行った結果の個数が一致したら、
    // 変更が無かったとみなし、trueを返して終了。
    SelectQuery<AvzTCirculationFile> dbquery =
      Database.query(AvzTCirculationFile.class);
    dbquery.andQualifier(ExpressionFactory.matchDbExp(
      _AvzTCirculationFile.TO_AVZ_TCIRCULATION_REQUEST_PROPERTY,
      request.getRequestId()));
    for (int i = 0; i < fileIDsize; i++) {
      dbquery.orQualifier(ExpressionFactory.matchDbExp(
        _AvzTCirculationFile.FILE_ID_PK_COLUMN,
        fileids[i]));
    }
    ResultList<AvzTCirculationFile> files = dbquery.getResultList();

    if (files.size() == fileIDsize
      && (fileuploadList == null || fileuploadList.size() <= 0)) {
      return true;
    }

    SelectQuery<AvzTCirculationFile> query =
      Database.query(AvzTCirculationFile.class);
    query.andQualifier(ExpressionFactory.matchDbExp(
      _AvzTCirculationFile.TO_AVZ_TCIRCULATION_REQUEST_PROPERTY,
      request.getRequestId()));
    for (int i = 0; i < fileIDsize; i++) {
      Expression exp =
        ExpressionFactory.matchDbExp(
          _AvzTCirculationFile.FILE_ID_PK_COLUMN,
          Integer.parseInt(fileids[i]));
      query.andQualifier(exp.notExp());
    }
    // DB上でトピックに属すが、送られてきたFileIDにIDが含まれていないファイルのリスト(削除されたファイルのリスト)
    ResultList<AvzTCirculationFile> delFiles = query.getResultList();

    if (delFiles.size() > 0) {
      // ローカルファイルに保存されているファイルを削除する．
      File file = null;
      int delsize = delFiles.size();
      for (int i = 0; i < delsize; i++) {
        file =
          new File(CirculationUtils.getSaveDirPath(org_id, uid)
            + (delFiles.get(i)).getFilePath());
        if (file.exists()) {
          file.delete();
        }
      }
      // データベースから添付ファイルのデータ削除
      Database.deleteAll(delFiles);
    }

    // 追加ファイルが無ければtrueを返して終了
    if (fileuploadList == null || fileuploadList.size() <= 0) {
      return true;
    }

    // ファイル追加処理
    try {
      FileuploadLiteBean filebean = null;
      int size = fileuploadList.size();
      for (int i = 0; i < size; i++) {
        filebean = (FileuploadLiteBean) fileuploadList.get(i);

        // サムネイル処理
        String[] acceptExts = ImageIO.getWriterFormatNames();
        byte[] fileThumbnail =
          FileuploadUtils.getBytesShrinkFilebean(
            org_id,
            folderName,
            uid,
            filebean,
            acceptExts,
            FileuploadUtils.DEF_THUMBNAIL_WIDTH,
            FileuploadUtils.DEF_THUMBNAIL_HEIGTH,
            msgList);

        // String filename =
        // FileuploadUtils.getNewFileName(CirculationUtils.getSaveDirPath(
        // org_id,
        // uid));
        String filename = i + "_" + String.valueOf(System.nanoTime());

        // 新規オブジェクトモデル
        AvzTCirculationFile file = Database.create(AvzTCirculationFile.class);
        // 所有者
        file.setOwnerId(Integer.valueOf(uid));
        // リクエストID
        file.setToAvzTCirculationRequest(request);
        // ファイル名
        file.setFileName(filebean.getFileName());
        // ファイルパス
        file.setFilePath(CirculationUtils.getRelativePath(filename));
        // サムネイル画像
        if (fileThumbnail != null) {
          file.setFileThumbnail(fileThumbnail);
        }
        // 作成日
        file.setCreateDate(Calendar.getInstance().getTime());
        // 更新日
        file.setUpdateDate(Calendar.getInstance().getTime());

        // ファイルの移動
        // File srcFile =
        // FileuploadUtils.getAbsolutePath(org_id, uid, folderName, filebean
        // .getFileId());
        // File destFile = new File(getAbsolutePath(org_id, uid, filename));
        // FileuploadUtils.copyFile(srcFile, destFile);
        //
        // srcFile = null;
        // destFile = null;
        ALStorageService.copyTmpFile(uid, folderName, String.valueOf(filebean
          .getFileId()), FOLDER_FILEDIR_CIRCULATION, CATEGORY_KEY
          + ALStorageService.separator()
          + uid, filename);
      }

      // 添付ファイル保存先のフォルダを削除
      // File folder = FileuploadUtils.getFolder(org_id, uid, folderName);
      // FileuploadUtils.deleteFolder(folder);
      ALStorageService.deleteTmpFolder(uid, folderName);
    } catch (Exception e) {
      logger.error("Exception", e);
      return false;
    }
    return true;
  }

  // public static List getAuthorityUsers(RunData rundata, String groupname,
  // boolean includeLoginuser) {
  //
  // try {
  // // アクセス権限
  // ALAccessControlFactoryService aclservice = (ALAccessControlFactoryService)
  // ((TurbineServices) TurbineServices
  // .getInstance())
  // .getService(ALAccessControlFactoryService.SERVICE_NAME);
  // ALAccessControlHandler aclhandler = aclservice.getAccessControlHandler();
  //
  // List ulist = aclhandler.getAuthorityUsersFromGroup(rundata,
  // ALAccessControlConstants.POERTLET_FEATURE_WORKFLOW_REQUEST_SELF,
  // groupname, includeLoginuser);
  //
  // int recNum = ulist.size();
  //
  // List list = new ArrayList();
  //
  // UserLiteBean user;
  // DataRow dataRow;
  // // ユーザデータを作成し、返却リストへ格納
  // for (int j = 0; j < recNum; j++) {
  // dataRow = (DataRow) ulist.get(j);
  // user = new UserLiteBean();
  // user.initField();
  // user.setUserId(((Integer) ALEipUtils.getObjFromDataRow(dataRow,
  // _TurbineUser.USER_ID_PK_COLUMN)).intValue());
  // user.setName((String) ALEipUtils.getObjFromDataRow(dataRow,
  // TurbineUser.LOGIN_NAME_COLUMN));
  // user.setAliasName((String) ALEipUtils.getObjFromDataRow(dataRow,
  // TurbineUser.FIRST_NAME_COLUMN), (String) ALEipUtils
  // .getObjFromDataRow(dataRow, TurbineUser.LAST_NAME_COLUMN));
  // list.add(user);
  // }
  // return list;
  // } catch (InstantiationException e) {
  // return null;
  // }
  //
  // }

  /**
   * 重要度を表す画像名を取得します。 <BR>
   * 1 : 高い : priority_high.gif <BR>
   * 2 : やや高い : priority_middle_high.gif <BR>
   * 3 : 普通 : priority_middle.gif <BR>
   * 4 : やや低い : priority_middle_low.gif <BR>
   * 5 : 低い : priority_low.gif <BR>
   * 
   * @param i
   * @return
   */
  public static String getPriorityImage(int i) {
    String[] temp =
      {
        "priority_high.gif",
        "priority_middle_high.gif",
        "priority_middle.gif",
        "priority_middle_low.gif",
        "priority_low.gif" };
    String image = null;
    try {
      image = temp[i - 1];
    } catch (Exception ex) {
      // logger.error("Exeption", ex);
    }
    return image;
  }

  /**
   * 重要度を表す文字列を取得します。 <BR>
   * 1 : 高い : priority_high.gif <BR>
   * 2 : やや高い : priority_middle_high.gif <BR>
   * 3 : 普通 : priority_middle.gif <BR>
   * 4 : やや低い : priority_middle_low.gif <BR>
   * 5 : 低い : priority_low.gif <BR>
   * 
   * @param i
   * @return
   */
  public static String getPriorityString(int i) {
    String[] temp = { "高い", "やや高い", "普通", "やや低い", "低い" };
    String string = null;
    try {
      string = temp[i - 1];
    } catch (Exception ex) {
      // logger.error("Exeption", ex);
    }
    return string;
  }

  /**
   * Date のオブジェクトを指定した形式の文字列に変換する．
   * 
   * @param date
   * @param dateFormat
   * @return
   */
  public static String translateDate(Date date, String dateFormat) {
    if (date == null) {
      return "Unknown";
    }

    // 日付を表示形式に変換
    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
    sdf.setTimeZone(TimeZone.getDefault());
    return sdf.format(date);
  }

  public static Date getEmptyDate() {
    Calendar cal = Calendar.getInstance();
    cal.set(DUMMY_YEAR, 11, 31);
    return cal.getTime();
  }

  public static boolean isEmptyDate(Date date) {
    if (date == null) {
      return false;
    }
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return cal.get(Calendar.YEAR) == DUMMY_YEAR;
  }

  /**
   * 依頼の詳細情報を取得する。
   * 
   * @param rundata
   * @param context
   */
  public static Object getResultDataDetail(Object obj, long userId) {
    try {
      AvzTCirculationRequest record = (AvzTCirculationRequest) obj;
      CirculationDetailResultData rd = new CirculationDetailResultData();
      rd.initField();
      rd.setOwnerId(record.getUserId().longValue());
      rd.setRequestName(record.getRequestName());
      rd.setRequestId(record.getRequestId().longValue());
      rd.setCategoryId(record
        .getToAvzTCirculationCategory()
        .getCategoryId()
        .longValue());
      rd.setCategoryName(record
        .getToAvzTCirculationCategory()
        .getCategoryName());
      rd.setPriorityString(getPriorityString(record.getPriority().intValue()));
      rd.setNote(record.getNote());
      rd.setCreateUser(ALEipUtils.getUserFullName(record.getUserId()));
      rd.setProgressString(CirculationUtils
        .getCountOfConfirmedAvzTCirculationRequestMap(record)
        + "/"
        + CirculationUtils.getCountOfAvzTCirculationRequestMap(record));

      List<CirculationResponseRecordData> drList =
        new ArrayList<CirculationResponseRecordData>();
      ALEipUser user = null;
      AvzTCirculationRequestMap map = null;
      CirculationResponseRecordData drd = null;
      ResultList<AvzTCirculationRequestMap> maps =
        getAvzTCirculationRequestMaps(record);
      int size = maps.size();
      for (int i = 0; i < size; i++) {
        map = maps.get(i);
        drd = new CirculationResponseRecordData();
        drd.initField();

        user = ALEipUtils.getALEipUser(map.getUserId().intValue());
        drd.setUserId(map.getUserId().intValue());
        drd.setUserAliasName(user.getAliasName().getValue());
        drd.setStatus(map.getStatus());
        drd.setStatusString(getStatusString(map.getStatus()));
        drd.setNote(map.getNote());
        drd.setUpdateDate(translateDate(map.getUpdateDate(), "yyyy年M月d日H時m分"));
        drList.add(drd);
      }

      // ログインユーザーのデータを先頭に移す。
      List<CirculationResponseRecordData> changedDrList =
        new ArrayList<CirculationResponseRecordData>();
      CirculationResponseRecordData myData = null;
      for (CirculationResponseRecordData d : drList) {
        if (d.getUserId().getValue() == userId) {
          myData = d;
          continue;
        }
        changedDrList.add(d);
      }
      if (myData != null) {
        changedDrList.add(0, myData);
      }
      rd.setResponseRecords(changedDrList);

      // ファイルリスト
      ResultList<AvzTCirculationFile> list =
        getSelectQueryForFiles(record.getRequestId().intValue())
          .getResultList();
      if (list != null && list.size() > 0) {
        ArrayList attachmentFileList = new ArrayList();
        FileuploadBean filebean = null;
        AvzTCirculationFile file = null;
        int lsize = list.size();
        for (int i = 0; i < lsize; i++) {
          file = list.get(i);
          String realname = file.getFileName();
          javax.activation.DataHandler hData =
            new javax.activation.DataHandler(
              new javax.activation.FileDataSource(realname));

          filebean = new FileuploadBean();
          filebean.setFileId(file.getFileId().intValue());
          filebean.setFileName(realname);
          if (hData != null) {
            filebean.setContentType(hData.getContentType());
          }
          filebean.setIsImage(FileuploadUtils.isImage(realname));
          attachmentFileList.add(filebean);
        }
        rd.setAttachmentFiles(attachmentFileList);
      }

      rd.setCreateDate(translateDate(record.getCreateDate(), "yyyy年M月d日H時m分"));
      rd.setUpdateDate(translateDate(record.getUpdateDate(), "yyyy年M月d日H時m分"));
      if (!CirculationUtils.isEmptyDate(record.getLimitDate())) {
        rd.setLimitDate(translateDate(record.getLimitDate(), "yyyy年M月d日"));
      }
      return rd;
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return null;
    }
  }

  /**
   * 
   * @param status
   */
  public static String getStatusString(String status) {
    String res = "";
    if (DB_STATUS_REQUEST.equals(status)) {
      res = "未確認";
    } else if (DB_STATUS_CONFIRM.equals(status)) {
      res = "確認済";
    }
    return res;
  }

  /**
   * ファイル検索のクエリを返します
   * 
   * @param requestid
   *            ファイルを検索するリクエストのid
   * @return query
   */
  private static SelectQuery<AvzTCirculationFile> getSelectQueryForFiles(
      int requestid) {
    SelectQuery<AvzTCirculationFile> query =
      Database.query(AvzTCirculationFile.class);
    Expression exp =
      ExpressionFactory.matchDbExp(
        _AvzTCirculationRequest.REQUEST_ID_PK_COLUMN,
        Integer.valueOf(requestid));
    query.setQualifier(exp);
    return query;
  }

  /**
   * 現在日時と指定した日時とを比較する．
   * 
   * @param endDate
   * @return 現在日時 < 指定日時 ：LIMIT_STATE_BEFORE <br>
   *         現在日時 == 指定日時 ：LIMIT_STATE_TODAY <br>
   *         現在日時 > 指定日時 ：LIMIT_STATE_AFTER
   */
  public static int getLimitState(Date endDate) {
    if (endDate == null) {
      return LIMIT_STATE_BEFORE;
    }

    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    Date nowDate = calendar.getTime();
    calendar.setTime(endDate);
    Date endDate1 = calendar.getTime();

    if (calendar.get(Calendar.YEAR) == 9999
      && calendar.get(Calendar.MONTH) == 11
      && calendar.get(Calendar.DATE) == 31) {
      // 締め切り日時が未指定の場合
      return LIMIT_STATE_BEFORE;
    }

    int result = nowDate.compareTo(endDate1);
    if (result < 0) {
      result = LIMIT_STATE_BEFORE;
    } else if (result == 0) {
      result = LIMIT_STATE_TODAY;
    } else {
      result = LIMIT_STATE_AFTER;
    }
    return result;
  }

  /**
   * ファイルオブジェクトモデルを取得します。 <BR>
   * 
   * @param rundata
   * @param context
   * @return
   */
  public static AvzTCirculationFile getAvzTCirculationFile(RunData rundata)
      throws ALPageNotFoundException, ALDBErrorException {
    try {
      int attachmentIndex =
        rundata.getParameters().getInt("attachmentIndex", -1);
      if (attachmentIndex < 0) {
        // ID が空の場合
        logger.debug("[CirculationUtils] Empty ID...");
        throw new ALPageNotFoundException();

      }

      SelectQuery<AvzTCirculationFile> query =
        Database.query(AvzTCirculationFile.class);
      Expression exp =
        ExpressionFactory.matchDbExp(
          _AvzTCirculationFile.FILE_ID_PK_COLUMN,
          Integer.valueOf(attachmentIndex));
      query.andQualifier(exp);
      ResultList<AvzTCirculationFile> files = query.getResultList();
      if (files == null || files.size() == 0) {
        // 指定した ID のレコードが見つからない場合
        logger.debug("[WorkflowUtils] Not found ID...");
        throw new ALPageNotFoundException();
      }
      return files.get(0);
    } catch (Exception ex) {
      logger.error("[WorkflowUtils]", ex);
      throw new ALDBErrorException();
    }
  }

  public static void clearFilter(RunData rundata, Context context) {
    // 一覧表示画面のフィルタに設定されているカテゴリのセッション情報を削除
    String filtername =
      CirculationSelectData.class.getName() + ALEipConstants.LIST_FILTER;
    ALEipUtils.removeTemp(rundata, context, filtername);
  }

}
